之前的传统做法,对象都是通过new出来的,如果需求变更,增加代码的同时需要去改动原有的代码,程序适应不了需求的变更。如果代码量大,修改的代价非常高。
举个简单的例子:一个获取用户信息的接口,有如下几个类
- UserDao
- UserDaoImpl
- UserServiceDao
- UserServiceDaoImpl
获取用户代码:
service中调用dao的方法
后面有需求变更,需要从MySQL和Oracle中获取用户,加了两个接口实现类
那么在调用的时候就得修改代码
为了解决这个问题,可以用set进行动态实现值的注入
在使用set方法之后,已经发生了革命性的变化!
- 之前,程序是主动创建对象!控制权在程序猿手上!
- 使用了set注入之后,程序不再具有主动性,而是变成了被动地接收对象
这种思想,从本质上解决了问题,程序猿不用再去管理对象的创建了。系统的耦合性大大降低,可以更加专注地在业务实现上。这是IOC的原型!
2、IOC本质控制反转loc(lnversion Of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是lOC的另一种说法。没有lOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
IOC是Spring框架的核心内容,使用多种方式完美的实现了IOC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IOC。
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
通俗的话讲:用户访问的service(业务)层,逻辑代码都是在业务层,假如之前只有一个Mysql实现,现在要加一个Oracle实现,以及一些其他的实现,每加一种实现,用户用不着去改变什么,主动权在业务层,由程序控制调用什么实现,不管最终有多少种实现,用户都只调用业务层。
用了IOC思想之后,程序架构没有变化,只是把程序主动权移交了,之前的主动权在业务层,现在移交到用户手中,由用户选择调用什么实现。
这就是最大的区别,主动权的移交。
3.2. 编写代码org.springframework spring-webmvc 5.1.10.RELEASE junit junit 4.12 test
编写一个Hello实体类
public class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show() {
System.out.println("this is hello");
}
}
编写我们的spring配置文件,官方的默认配置文件名为applicationContext.xml,这里我们暂时命名为beans.xml
进行测试
@Test
public void fun1(){
//获取spring上下文对象,解析beans.xml文件,生成管理相应的Bean对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//getBean : 参数即为spring配置文件中bean的id .
Hello hello = (Hello) context.getBean("hello");
hello.show();
}
3.3. 思考这里new ClassPathXmlApplicationContext()的时候有个好记的小技巧,拼音缩写:cpx(吃螃蟹)
- Hello 对象是谁创建的 ? 【 hello 对象是由Spring创建的 】
- Hello 对象的属性是怎么设置的 ? 【hello 对象的属性是由Spring容器设置的 】
分析一下xml配置文件中的内容:
bean标签就是一个对象,class是对应的类型,这里就是相当于new了一个Hello
正常Java中,创建一个对象是 类型 变量名 = new 类型();
在IOC中:
- bean标签中id就是变量名
- class是对象的全路径
- property相当于给对象中的相应属性设置一个值
这个过程就叫控制反转 :
- 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
- 反转 : 程序本身不创建对象 , 而变成被动的接收对象 .
依赖注入 : 就是利用set方法来进行注入的
IOC是一种编程思想,由主动的编程变成被动的接收
可以通过newClassPathXmlApplicationContext去浏览一下底层源码
newClassPathXmlApplicationContext UML图:
在刚刚的案例中, 新增一个Spring配置文件beans.xml
测试
@Test
public void test2(){
// 获取ApplicationContext;拿到spring的容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("ServiceImpl");
serviceImpl.getUser();
}
OK , 到了现在 , 我们彻底不用在程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IOC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !



