Spring中IOC的理解
Spring中IOC的理解
1、什么是IOC?
(1)控制反转。把对象创建和对象间的调用过程交给Spring进行管理。
(2)使用IOC的目的:为了耦合度降低。
2、IOC底层原理?
(1)xml解析、工厂模式、反射
(2)图解
原始调用方式(耦合度太高,dao如果变了service也要跟着变):
引入工厂模式解除上面两个类的耦合度(但是工厂和service出现了新的耦合):
IOC解耦过程(进一步降低耦合度)
第一步:xml配置文件,配置创建的对象,示例:<bean id="aaa" class="xxx.dao"></bean>
第二步:有service和dao类,创建工厂类,示例:
IOC接口
- IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
- Spring提供IOC容器实现两种方式:(两个接口)
- BeanFactory:最基本接口,供内部人员使用。加载配置文件时不会去创建对象,在获取对象或者使用对象时才去创建对象。(.getBean方法时)
- ApplicationContext:BeanFactory接口的一个子接口。提供了更多功能,一般由开发人员使用。加载配置文件时就会把在配置文件中对象进行创建。
3.ApplicationContext的主要实现类(File那个类是盘里全路径,Class那个是类路径位置):
IOC操作:Bean管理
1、什么是Bean管理(2个操作)
(1)Spring创建对象
(2)Spring注入属性
2、Bean管理操作有两种方式
(1)基于xml配置文件方式实现
(2)基于注解方式实现
IOC操作Bean管理(基于xml方式)
1、基于xml创建对象
<bean id="aaa" class="xxx.dao"></bean>
bean中常用属性:
id:唯一标识
class:类全路径
创建对象时,默认执行无参构造,完成对象创建。
2、基于xml注入属性
(1)DI:依赖注入,注入属性,是IOC一种实现
第一种注入方式:使用set方法进行注入
创建一个类,创建其对应set方法;
在Spring配置文件中配置对象创建,配置属性注入,示例如下:
<bean id="book" class="org.zhaojianhui.Spring.Book">
<property name="name" value="我的世界"/>
<property name="price" value="15.0"/>
</bean>
第二种注入方式:使用有参构造进行注入
创建一个类,定义属性以及有参构造
//有参构造注入
public Book(String name, String price) {
this.name = name;
this.price = price;
}
Spring配置文件中编写:
<bean id="book" class="org.zhaojianhui.Spring.Book">
<constructor-arg name="name" value="我的爱人"></constructor-arg>
<constructor-arg name="price" value="16.0"></constructor-arg>
</bean>
P名称空间注入(底层还是set注入):
1、加一个p命名空间
2、进行属性注入:
xml中其他属性注入:
1、空值注入

2、属性值包含特殊符号:

转义<>:< >
注入属性:外部Bean
- 创建service类和dao类,省略此处。
2.在service中调用dao
//创建userDao类型,申明set方法 private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add() { System.out.println("service add!!!"); userDao.update(); }
3.在Spring配置文件中进行配置
<!--service和dao对象创建--> <bean id="userService" class="org.zhaojianhui.Spring.service.UserService"> <!--注入userdao对象,name是类里的属性名称, ref是创建UserDao中bean标签的id,注入外部bean--> <property name="userDao" ref="userDao"></property> </bean> <bean id="userDao" class="org.zhaojianhui.Spring.dao.UserDaoImpl"></bean>
注入属性:内部Bean
- 一对多关系:例如部门对员工示例
//部门类 public class Dept { private String dname; public void setDname(String dname) { this.dname = dname; } }
//员工类 public class Emp { private String name; private String gender; private Dept dept; public void setDept(Dept dept) { this.dept = dept; } public void setName(String name) { this.name = name; } public void setGender(String gender) { this.gender = gender; } }
2.在Spring配置文件中进行配置
<!--内部bean--> <bean id="emp" class="org.zhaojianhui.Spring.Bean.Emp"> <property name="name" value="zs"></property> <property name="gender" value="男"></property> <!--对象类型属性--> <property name="dept"> <bean id="demp" class="org.zhaojianhui.Spring.Bean.Dept"> <property name="dname" value="安保部"></property> </bean> </property> </bean>
级联赋值:
写法1:
<bean id="emp" class="org.zhaojianhui.Spring.Bean.Emp"> <property name="name" value="zs"></property> <property name="gender" value="男"></property> <!--对象类型属性--> <property name="dept" ref="depts"></property> </bean> <bean id="depts" class="org.zhaojianhui.Spring.Bean.Dept"> <property name="dname" value="安保部"></property> </bean>
写法2:
<property name="dept.dname" value="体育部"></property>,对应Emp实体需要生成dept属性的getter方法才能完成!
IOC操作Bean管理(xml注入集合属性)
1、注入数组类型属性
2、注入List类型属性
3、注入Map类型属性
配置文件中代码示例如下:
<!--数组、List、Map注入-->
<bean id="stu" class="org.zhaojianhui.Spring.Bean.Stu">
<property name="course">
<array>
<value>语文</value>
<value>数学</value>
</array>
</property>
<property name="list">
<list>
<value>张三</value>
<value>三儿</value>
</list>
</property>
<property name="map">
<map>
<entry key="JAVA" value="java">
</entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
</bean>
在集合里设置对象类型值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!--注入list集合类型,值是对象--> <property name= "courseList" > <list> <ref bean= "course1" ></ref> <ref bean= "course2" ></ref> </list> </property> </bean> <bean id= "course1" class = "org.zhaojianhui.Spring.Bean.Course" > <property name= "cname" value= "Spring" ></property> </bean> <bean id= "course2" class = "org.zhaojianhui.Spring.Bean.Course" > <property name= "cname" value= "MVC" ></property> </bean> |
把集合注入部分提取出来
1、在配置文件中引入一个名称空间util
1 2 3 4 5 6 7 8 9 10 | <?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/beans http: //www.springframework.org/schema/beans/spring-beans.xsd http: //www.springframework.org/schema/util http: //www.springframework.org/schema/util/spring-util.xsd"> </beans> |
2、使用util标签完成list集合提取注入
1 2 3 4 5 6 7 8 9 10 11 12 | <!--提取list集合属性注入--> <util:list id= "list" > <value>w</value> <value>q</value> <value>r</value> </util:list> <!--注入使用--> <bean id= "stu" class = "org.zhaojianhui.Spring.Bean.Stu" > <property name= "list" ref= "list" > </property> </bean> |
IOC操作Bean管理(FactoryBean)
1、Spring有两种Bean,一种普通Bean,另外一种工厂Bean
2、普通Bean:在配置文件中定义Bean类型就是返回类型
3、工厂Bean:在配置文件中定义Bean类型可以和返回类型不一样
Bean的作用域:
默认单例,可以在配置文件中修改作用域,在bean标签的scope属性用于设置,属性值有singleton,prototype(多例),request,session
区别:
设置为单例时,加载配置文件时就会创建单例对象,设置为多例时候不是在加载配置文件时创建对象,而是在调用getBean方法时候创建多实例对象。
Bean的生命周期:
1、通过构造器创建bean示例(无参构造)
2、为bean的属性设置值和对其他bean的引用(调用set方法)
把bean实例传递给bean后置处理器方法(如果使用了后置处理器就会多两个步骤,即实现BeanPostProcessor方法)
3、调用bean的初始化方法
把bean实例传递给bean后置处理器方法
4、bean可以使用了(对象获取到了)
5、当容器关闭时,调用Bean的销毁方法
XML自动装配
1、基于名称 2、基于类型
1 2 3 4 5 6 | <!--自动装配,bean标签属性autowire配置自动装配,byName根据属性名称注入(bean的id值和类属性名称一样),byType根据属性类型注入 (但是相同类型的bean不能定义多个)--> <bean id= "emp" class = "org.zhaojianhui.Spring.Bean.Emp" autowire= "byName" ></bean> <bean id= "dept" class = "org.zhaojianhui.Spring.Bean.Dept" > <property name= "dname" value= "开发部门" ></property> </bean> |
引入外部属性文件(以数据库信息为例):
1、直接配置数据库信息
2、通过引入外部属性文件配置数据库连接池
1、引入context命名空间
2、spring配置文件中引入外部文件
1 2 | <!--引入外部属性文件--> <context:property-placeholder location= "classpath:jdbc.properties" /> |
3、使用${属性}填充内容
1 2 3 4 5 6 | <bean id= "dataSource" class = "com.alibaba.druid.pool.DruidDataSource" > <property name= "driverClassName" value= "${prop.driverClass}" ></property> <property name= "url" value= "${prop.url}" ></property> <property name= "username" value= "${prop.userName}" ></property> <property name= "password" value= "${prop.password}" ></property> </bean> |
IOC操作Bean管理(基于注解方式)
1、什么是注解?
1、@注解名称,注解可以作用在类、方法、属性上
2、使用目的:简化xml配置
2、Spring针对Bean管理中创建对象提供注解:
1、@Component:
2、@Service:
3、@Controller:
4、@Repository:用于dao层一般
3、基于注解方式演示对象创建(注解的value值默认为类首字母小写)
第一步:引入aop依赖
第二步:开启组建扫描
1 2 | <!--开启组件扫描--> <context:component-scan base- package = "org.zhaojianhui.Spring" ></context:component-scan><br><br> |
开启组件扫描细节(设置哪些扫描哪些不扫描):
1 2 3 4 | <!--use- default -filters= "false" ,表示现在不使用默认filter,自己配置filter,下面配置表示只扫描包下带有Controller注解的类--> <context:component-scan base- package = "org.zhaojianhui.Spring" use- default -filters= "false" > <context:include-filter type= "annotation" expression= "org.springframework.stereotype.Controller" /> </context:component-scan> |
基于注解方式实现属性注入:
(1) @Autowired:根据属性类型进行自动装配
1、在service中注入dao对象(此时加了注解后不需要set方法)
@Service public class UserService { @Autowired private UserDao userDao; public void add() { System.out.println("service add!!!"); userDao.update(); } }
(2)@Qualifier(需要和Autoqired一起使用):根据属性名称注入
1 2 3 | @Autowired @Qualifier (value = "userDaoImp1" ) private UserDao userDao; |
(3)@Resource:可以根据名称/类型注入
@Resource//根据类型注入 @Resource(name = "userDaoImp1")//根据名称注入 private UserDao userDao;
(4)@Value:注入普通类型
1 2 | @Value (value = "abc" ) private String name; |
纯注解开发:
(1)创建配置类,替代xml文件
@Configuration//作为配置类,替代xml文件 @ComponentScan(basePackages = {"org.zhaojianhui.Spring"})//需要扫描的包 public class SpringConfig { }
(2)编写测试类
1 2 3 4 5 6 7 8 9 | public void test() { // ApplicationContext appo = new ClassPathXmlApplicationContext("bean2.xml"); ApplicationContext appo = new AnnotationConfigApplicationContext(SpringConfig. class );; //加载配置类 UserService userService = appo.getBean( "userService" , UserService. class ); System.out.println(userService); userService.add(); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!