Spring之IOC

article/2025/7/6 1:05:46

Spring

  • 一、文档
  • 二、依赖注入方式
  • 三、注入其他类型
    • 3.1 设置null空值:使用null标签
    • 3.2 含特殊字符:使用CDATA
  • 四、注入外部bean、内部bean
    • 4.1 注入属性中的外部bean
    • 4.2 注入属性中的内部bean
    • 4.3 注入属性级联赋值
  • 五、注入集合属性
    • 5.1 注入集合属性
    • 5.2 把集合注入部分提取出来
  • 六、工厂bean
  • 七、bean作用域:scope参数
    • 7.1 标准作用域
    • 7.2 Web 相关作用域
  • 八、bean生命周期
  • 九、自动装配
    • 9.1 autowire属性(很少用)
  • 十、注解
    • 10.1 Spring针对bean管理中创建对象提供注解有:@Service、@Controller、@Component、@Repository
    • 10.2

一、文档

spring官网

二、依赖注入方式

1、使用set方法实现注入(bean中使用property)
2、使用有参构造实现注入(bean中使用constructor-arg)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--1、完成User对象的创建bean标签:id属性:Bean的唯一标识符class属性:要创建对象所在类的全路径(包名称+类名称)--><bean id="user" class="org.example.User"><!--使用property标签完成属性注入:name:类里面属性名称,value:给属性赋值--><property name="name" value="John Doe" /><property name="age" value="30" /></bean><!--2 有参数构造注入属性--><bean id="orders" class="org.example.Orders"><constructor-arg name="oname" value="电脑" /><constructor-arg name="address" value="China" /></bean></beans>

orders类:

package org.example;public class Orders {private String oname;private String address;//有参数构造方法public Orders(String oname, String address) {this.oname = oname;this.address = address;}public void testDemo() {System.out.println("orders:=======" + oname + "======" + address);}
}

user类:

package org.example;public class User {private String name;private Integer age;// 使用set方法实现注入public void setName(String name) {this.name = name;}public void setAge(Integer age) {this.age = age;}public void testDemo() {System.out.println("user:=======" + name + "======" + age);}
}

测试代码:

package org.example;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Testdemo {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");User user = context.getBean("user", User.class);System.out.println("hello :" + user);user.testDemo();Orders orders = context.getBean("orders", Orders.class);System.out.println("hello :" + orders);orders.testDemo();}
}

三、注入其他类型

3.1 设置null空值:使用null标签

 <!--使用null标签:表示注入空值--><property name="age"><null/></property>

3.2 含特殊字符:使用CDATA

 <constructor-arg name="address"><value><![CDATA[<<南京>>]]></value></constructor-arg>

结果:
在这里插入图片描述

四、注入外部bean、内部bean

4.1 注入属性中的外部bean

 <!--4 service和dao对象创建--><bean id="userService" class="service.UserService"><!--注入userDaoImpl对象  name:类里面属性名称,ref:创建userDao对象bean标签id值--><property name="userDao" ref="userDaoImpl"/></bean><bean id="userDaoImpl" class="dao.UserDaoImpl"></bean>

UserService:

package service;import dao.UserDao;public class UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}public void add() {System.out.println("service add...");userDao.add();}
}

dao先定义接口:

package dao;public interface UserDao {public void add();
}

实现dao:

package dao;import org.example.User;public class UserDaoImpl implements UserDao  {@Overridepublic void add() {System.out.println("UserDaoImpl add...");}
}

测试代码:

package dao;import org.example.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserService;public class Testdemo {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");UserService userService = context.getBean("userService", UserService.class);System.out.println("hello :" + userService);userService.add();}
}

运行结果:
在这里插入图片描述

4.2 注入属性中的内部bean

<!--内部bean--><bean id="emp" class="bean.Emp"><property name="ename" value="tom"></property><property name="gender" value=""></property><!-- 设置对象类型属性 (内部 bean 不需要指定 id 属性,因为它是内部使用)--><property name="dept"><bean class="bean.Dept"><property name="dname" value="研发部"></property></bean></property></bean>

Dept:

package bean;public class Dept {private String dname;public void setDname(String dname) {this.dname = dname;}public String getDname() {return dname;}@Overridepublic String toString() {return super.toString();}
}

Emp:

package bean;public class Emp {private String ename;private String gender;//员工属于某一部门,使用对象形式表示private Dept dept;public void setEname(String ename) {this.ename = ename;}public void setGender(String gender) {this.gender = gender;}public void setDept(Dept dept) {this.dept = dept;}public void show(){System.out.println("员工姓名:"+ename+",性别:"+gender+",部门:"+dept.getDname());}
}

运行结果:
在这里插入图片描述

4.3 注入属性级联赋值

<!--级联赋值--><bean id="emp" class="bean.Emp"><property name="ename" value="tom"></property><property name="gender" value=""></property><!-- 级联赋值--><property name="dept" ref="dept"></property></bean><bean id="dept" class="bean.Dept"><property name="dname" value="财务部"></property></bean>

其他同4.2,运行结果如下:
在这里插入图片描述

五、注入集合属性

5.1 注入集合属性

 <!--集合属性--><bean id="stu" class="collectType.Student"><property name="coureses"><array><value>java课程</value><value>数据库课程</value></array></property><property name="list"><list><value>张三</value><value>李四</value></list></property><property name="set"><set><value>张三</value><value>李四</value></set></property><property name="map"><map><entry key="1" value="java"></entry><entry key="2" value="数据库"></entry></map></property><!--注入list集合类型,值是对象--><property name="courseList"><list><ref bean="course1"></ref><ref bean="course2"></ref></list></property></bean><!--创建多个course对象--><bean id="course1" class="collectType.Course"><property name="cname" value="spring课程"></property></bean><bean id="course2" class="collectType.Course"><property name="cname" value="springboot课程"></property></bean>

course:

package collectType;public class Course {private String cname;public void setCname(String cname) {this.cname = cname;}@Overridepublic String toString() {return "Course{" +"cname='" + cname + '\'' +'}';}
}

Student:

package collectType;import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.List;public class Student {// 数组类型属性private String[] coureses;private List<String> list;private List<Course> courseList;private Set<String> set;private Map<String, String> map;public void setList(List<String> list) {this.list = list;}public void setSet(Set<String> set) {this.set = set;}public void setMap(Map<String, String> map) {this.map = map;}public void setCoureses(String[] coureses) {this.coureses = coureses;}public void setCourseList(List<Course> courseList) {this.courseList = courseList;}public void show() {System.out.println(Arrays.toString(coureses));System.out.println(list);System.out.println(set);System.out.println(map);System.out.println(courseList);}
}

运行结果:
在这里插入图片描述

5.2 把集合注入部分提取出来

(1)xmlns:util空间,注意是http
(2)util:list
(3)ref中使用util:list标签的id名

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsd"><!--1、提取list集合类型属性注入--><util:list id="bookList"><value>活着</value><value>在人间</value><value>我与地坛</value></util:list><!--2、提取list集合类型属性注入--><bean id="book" class="collectType.Books"><property name="list" ref="bookList"></property></bean>
</beans>

book:

package collectType;import java.util.List;public class Books {private List<String> list;public void setList(List<String> list) {this.list = list;}public void show(){System.out.println(list);}
}

六、工厂bean

<bean id="myBean" class="collectType.MyBean"></bean>

工厂bean:不直接返回自身实例,而是通过getObject()方法返回另一个对象

package collectType;import org.springframework.beans.factory.FactoryBean;public class MyBean implements FactoryBean<Course> {@Overridepublic Course getObject() throws Exception {//Course course = new Course();course.setCname("java");return course;}@Overridepublic Class<?> getObjectType() {return null;}@Overridepublic boolean isSingleton() {return FactoryBean.super.isSingleton();}
}

运行结果:
在这里插入图片描述

七、bean作用域:scope参数

<bean id="user" class="org.example.User" scope="prototype">   </bean>

7.1 标准作用域

​1、Singleton (单例作用域)​​

  • 默认作用域
  • 每个 Spring IoC 容器中只存在一个 Bean 实例
  • 所有请求都返回同一个实例
  • 适用于无状态 Bean

2、​Prototype (原型作用域)​​

  • 每次请求都创建一个新的 Bean 实例
  • 适用于有状态的 Bean
  • Spring 不管理原型 Bean 的完整生命周期

7.2 Web 相关作用域

​3、Request (请求作用域)​​

  • 每个 HTTP 请求创建一个新的 Bean 实例
  • 仅在 Web 应用中可用

4、Session (会话作用域)​​

  • 每个 HTTP Session 创建一个 Bean 实例
  • 用户会话期间保持相同实例
  • 仅在 Web 应用中可用

5、​Application (应用作用域)​​

  • 每个 ServletContext 创建一个 Bean 实例
  • 类似于单例,但在 Servlet 容器中每个应用有一个实例
  • 仅在 Web 应用中可用

6、WebSocket (WebSocket 作用域)​​

  • 每个 WebSocket 会话创建一个 Bean 实例
  • 在 WebSocket 会话期间保持相同实例

八、bean生命周期

Spring Bean 的生命周期指的是从 Bean 的创建到销毁的整个过程。
init-method和destroy-method

 <bean id="user" class="org.example.User"  init-method="init" destroy-method="destroy"><!--使用property标签完成属性注入:name:类里面属性名称,value:给属性赋值--><property name="name" value="John Doe" />
<!--        <property name="age" value="30" />--><!--null标签:表示注入空值--><property name="age"><null/></property></bean>

user类:

package org.example;public class User {private String name;private Integer age;public User() {System.out.println("第一步:user无参构造");}// 使用set方法实现注入public void setName(String name) {this.name = name;System.out.println("第二步:调用set方法设置属性值" + name);}public void setAge(Integer age) {this.age = age;System.out.println("第二步:调用set方法设置属性值" + age);}public void init(){System.out.println("第三步:初始化bean");}public void destroy(){System.out.println("第五步:销毁bean");}public void testDemo() {System.out.println("user:=======" + name + "======" + age);}
}

测试:

package org.example;import dao.UserDaoImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Testdemo {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");User user = context.getBean("user", User.class);System.out.println("第四步:获取创建的bean实例对象 :" + user);// 手动让bean实例销毁((ClassPathXmlApplicationContext) context).close();}
}

运行结果:
在这里插入图片描述

九、自动装配

9.1 autowire属性(很少用)

<!--实现自动装配:bean标签属性autowire,配置自动装配byName 根据属性名称注入,注入的bean的id值需和类的属性名称一样byType 根据属性类型注入,得保证类型唯一--><bean id="emp" class="bean.Emp" autowire="byName"><property name="ename" value="tom"></property><property name="gender" value=""></property></bean><bean id="dept" class="bean.Dept"><property name="dname" value="测试部"></property></bean>

十、注解

注解可用于类、方法、属性

10.1 Spring针对bean管理中创建对象提供注解有:@Service、@Controller、@Component、@Repository

 <!--开启组件扫描1、如果扫描多个包,多个包使用逗号隔开或扫描包上层目录-->
<context:component-scan base-package="demo"></context:component-scan>

在注解里面value属性值可以省略不写,默认值是类名首字母小写。

package demo;import org.springframework.stereotype.Service;@Service(value = "userService")
public class UserService {public void add(){System.out.println("test 123...");}
}

扫描demo包下不使用@Controller注解的类

  <context:component-scan base-package="demo"><!--排除组件--><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>

扫描demo包下使用@Service注解的类

 <context:component-scan base-package="demo" use-default-filters="false"><!--包含组件--><context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/></context:component-scan>

10.2


http://www.hkcw.cn/article/dpeUZGBnlj.shtml

相关文章

RAG的ETL Pipeline源码解读

原文链接&#xff1a;SpringAI(GA)&#xff1a;RAG下的ETL源码解读 教程说明 说明&#xff1a;本教程将采用2025年5月20日正式的GA版&#xff0c;给出如下内容 核心功能模块的快速上手教程核心功能模块的源码级解读Spring ai alibaba增强的快速上手教程 源码级解读 版本&a…

github 2FA双重认证丢失解决

文章目录 前言一. 凭借ssh 解锁步骤1.1 要求输入设备码1.2.进入二重验证界面1.3.开始2FA恢复1.4.选择使用ssh验证 二.预防措施2.1 云盘上传git_recover_codes.txt2.2 开启多源FA认证2.2.1 大陆无法使用手机验证码 三.参考资料 前言 场景&#xff1a;没有意识到github recovery …

【Java EE初阶 --- 多线程(初阶)】多线程的实现案例

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 文章目录 前言单例模式实现单例模式…

BiliNote部署实践

​ 开源地址&#xff1a; https://github.com/JefferyHcool/BiliNote &#x1f680; 快速开始 1. 克隆仓库 git clone https://github.com/JefferyHcool/BiliNote.git cd BiliNote mv .env.example .env2. 启动后端&#xff08;FastAPI&#xff09; cd backend pip insta…

基于回归算法的心理健康预测(EDA + 预测)

心理健康涵盖情感、心理与社会福祉&#xff0c;影响认知、情绪和行为模式&#xff0c;决定压力应对、人际交往及健康决策&#xff0c;且在生命各阶段&#xff08;从童年至成年&#xff09;均至关重要。心理健康与身体健康同为整体健康的核心要素&#xff1a;抑郁会增加糖尿病、…

无他相机:专业摄影,触手可及

在数字摄影时代&#xff0c;手机摄影已成为许多人记录生活、表达创意的重要方式。无他相机正是这样一款专为摄影爱好者设计的相机应用程序&#xff0c;它不仅提供了专业级摄影设备的大部分功能&#xff0c;还通过简洁直观的操作界面&#xff0c;让每一位用户都能轻松上手&#…

Qt/C++编写GB28181服务端工具/绿色版开箱即用/对标wvp-gb28181/实时画面预览/录像回放下载

一、前言说明 使用过不少的gb28181服务端工具&#xff0c;绝大部分都是BS结构的&#xff0c;也就是直接在网页上运行&#xff0c;比如easynvr、liveqing等&#xff0c;也有个知名的开源国标项目叫wvp&#xff0c;总体感觉性能都不如意&#xff0c;理论上来说肯定不如直接CS结构…

ProxyPin抓APK数据包

ProxyPin抓APK数据包&#xff1a; 下载地址&#xff1a;https://github.com/wanghongenpin/proxypin 环境配置&#xff1a; 夜神模拟器&#xff0c;开心消消乐&#xff0c;ProxyPin.apk&#xff0c;ProxyPin.exe 使用步骤&#xff1a; ProxyPin.apk安装https证书&#xff0…

空间智能重塑未来治理

当上海复兴岛的战略空间更新与科创策源功能在时空创新实验基地实现耦合共生&#xff0c;当武汉马拉松的智慧安防系统通过"实景三维城市智眼"构筑起全域智能防线&#xff0c;我们正见证着空间智能技术重构城市治理范式的革命性变革。这场以数据为血脉、算法为神经、模…

FastAPI安全认证:从密码到令牌的魔法之旅

title: FastAPI安全认证:从密码到令牌的魔法之旅 date: 2025/06/02 13:24:43 updated: 2025/06/02 13:24:43 author: cmdragon excerpt: 在FastAPI中实现OAuth2密码流程的认证机制。通过创建令牌端点,用户可以使用用户名和密码获取JWT访问令牌。代码示例展示了如何使用Cry…

Java Script函数

1.认识JS函数 1.1程序中的foo、bar、baz 在学习编程中&#xff0c;你可能会经常看到foo、bar、baz这些名词 它们通常被用来作为函数、变量、文件的名称 目前已经编程了计算机编程的术语一部分 但是它们本身并没有特别的用途和意义 常常被称之为“伪变量”&#xff08;metasynt…

吴恩达MCP课程(5):mcp_chatbot_prompt_resource.py

前提条件&#xff1a; 1、吴恩达MCP课程&#xff08;5&#xff09;&#xff1a;research_server_prompt_resource.py 2、server_config_prompt_resource.json文件 {"mcpServers": {"filesystem": {"command": "npx","args"…

性能测试的概念和场景设计

一、什么是性能 性能的定义&#xff1a;性能是指系统或设备在执行特定任务时的时间效率和资源利用情况。可以从两个主要维度来理解&#xff1a; 时间维度&#xff1a; a、响应时间&#xff1a;指系统从接收用户请求到返回结果所需的时间。 b、吞吐量&#xff1a;指单位时间内…

【Java学习笔记】异常

异常&#xff08;Exception&#xff09; 一、基本介绍 在 Java 程序中&#xff0c;将运行中发生的不正常情况称为 “异常”&#xff0c;开发过程中的语法错误和运行时发生的异常情况是不一样的。 二、异常的分类 1. Error&#xff08;错误&#xff09;&#xff1a;Java 虚拟…

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Form Wave(表单label波动效果)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— FormWave组件 仓库地址&#xff1a;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;https://50-vue-projects.vercel.app/ &#x1f3af; 组件目标 构建一个美观、动态的登录表单&#xff0…

数据库系统概论(十六)数据库安全性(安全标准,控制,视图机制,审计与数据加密)

数据库系统概论&#xff08;十六&#xff09;数据库安全性 前言一、数据库安全性1. 什么是数据库安全性&#xff1f;2. 为何会存在安全问题&#xff1f; 二、安全标准的发展1. 早期的“开拓者”&#xff1a;TCSEC标准2. 走向国际统一&#xff1a;CC标准3. TCSEC和CC标准有什么不…

显示即战略:铁电液晶如何成为 “数字中国” 的 “像素基石”?

一、显示技术&#xff1a;数字时代的核心战略支点 &#xff08;一&#xff09;从 “视觉窗口” 到 “战略基础设施” 在数字经济蓬勃发展的当下&#xff0c;显示技术早已超越了单纯的 “视觉呈现” 范畴&#xff0c;成为连接人与数字世界的关键接口。从智能手机、平板电脑到车…

⚡️ Linux grep 命令参数详解

⚡️ Linux grep 用法及参数详解 &#x1f4d8; 1. grep 简介 grep 是 Linux/Unix 系统中用于文本搜索的命令&#xff0c;其全称为 Global Regular Expression Print&#xff0c;意为全局正则表达式打印器。 它根据给定的 模式&#xff08;pattern&#xff09; 对文件或标准…

Rust 变量与可变性

文章目录 变量与可变性常量遮蔽&#xff08;Shadowing&#xff09; 变量与可变性 Rust中变量默认是不可变的&#xff0c;这是 Rust 鼓励你编写更安全、易于并发代码的众多方式之一。不过&#xff0c;你仍然可以选择让变量可变。让我们来探讨 Rust 为什么鼓励你优先使用不可变性…

YOLOV7改进之融合深浅下采样模块(DSD Module)和轻量特征融合模块(LFI Module)

目录 一、研究背景​ 二. 核心创新点​ ​2.1 避免高MAC操作​ ​2.2 DSDM-LFIM主干网络​ 2.3 P2小目标检测分支​ ​3. 代码复现指南​ 环境配置 关键修改点 ​4. 实验结果对比​ 4.1 VisDrone数据集性能 4.2 边缘设备部署 4.3 检测效果可视化 ​5. 应用场景​ …