官方文档: https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/core.html#spring-core
控制反转IOC
(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
IOC是Spring框架的核心内容,使用多种方式完美的实现了IOC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从IOC容器中取出需要的对象。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
IOC理论推导
搭建项目
新建Maven项目,pom.xml到导入spring-webmvc依赖(也可称为包,导该依赖的好处就是:idea会默认帮我们导入spring的几个主要包),删除src目录,项目根目录下新建Module,并且选择maven项目(这样就可以在一个项目中,新建多个项目了(Module))
1 | <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> |
原来:
- UserDao 接口
1 | package com.ling.dao; |
- UserDaoImpl 实现类
1 | package com.ling.dao; |
- UserService 业务接口
1 | package com.ling.service; |
- UserServiceImpl 业务实现类
1 | package com.ling.service; |
在之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求,去修改原代码!如果程序代码量非常大,修改一次的成本代价就十分昂贵!
现在我们使用一个Set接口实现:
1 | package com.ling.service; |
- 之前,程序是主动创建对象!控制权在程序员手上
- 使用了set注入后,程序不再具有主动性,而是变成了被动的接收对象! ==控制反转==
这种思想从本质上解决了问题,我们不用再去管理对象的创建 。系统的耦合性大大降低~,可以更专注的在业务的实现上! 这是IOC的原型!
HelloSpring
1、编写一个HelloSpring实体类
1 | package com.ling.pojo; |
2、在resources目录下编写spring配置文件 , 这里命名为beans.xml
1 |
|
3、进行测试
1 | import com.ling.pojo.HelloSpring; |
结论:
- HelloSpring 对象是由Spring创建的
- HelloSpring 对象的属性是由Spring容器设置的
上面的过程就叫控制反转 :
控制 :
谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的 .
反转 :
程序本身不创建对象 , 而变成被动的接收对象 .
IOC创建对象的原理(方式)
使用无参构造新建对象,默认!
使用有参构造创建对象。
- 通过参数 下标赋值
1 | <!--通过下标赋值:下标为 0 即有参构造中的第一个参数--> |
- 通过参数类型赋值
1
2
3
4<!--通过参数类型赋值,但如果有两个参数都是String类型,则报错,所以不建议使用该方式-->
<bean id="user" class="com.ling.pojo.User">
<constructor-arg type="java.lang.String" value="编程之外"/>
</bean> - 通过参数名赋值
1
2
3
4<!--通过参数名称赋值,如这里的 name参数 -->
<bean id="user" class="com.ling.pojo.User">
<constructor-arg name="name" value="编程之外"/>
</bean>
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!