spring的控制反转(IOC)和依赖注入(DI)
IoC(控制反转)和DI(依赖注入)的理解
我们平时在开发java web程序的时候,每个对象在需要使用它的合作对象时,自己都要将它要合作对象创建出来(比如 new 对象),这个合作对象是由自己主动创建出来的。创建合作对象的主动权在自己手上,需要时候就主动创建,这样耦合性很高。在这稍微解释一下耦合性概念:A对象需要使用合作对象B来共同完成一件事,A要使用B,那么A就对B产生了依赖,也就是A和B之间存在一种耦合关系,并且是紧密耦合在一起。
但是这种高度的耦合性在使用了Spring之后就不一样了,创建合作对象B的工作是由Spring来做的,Spring创建好B对象,然后存储到一个容器里面,当A对象需要使用B对象时,Spring就从存放对象的那个容器里面取出A要使用的那个B对象,然后交给A对象使用,至于Spring是如何创建那个对象,以及什么时候创建好对象的,A对象不需要关心这些细节问题,A得到Spring给我们的对象之后,两个人一起协作完成要完成的工作即可。
所以控制反转IoC(Inversion of Control)是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方,比如转移交给了IoC容器,它就是一个专门用来创建对象的工厂,你要什么对象,它就给你什么对象,有了 IoC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IoC容器了,通过IoC容器来建立它们之间的关系。
DI(依赖注入)其实就是IOC的一种类型,还有一种是DL(Dependency Lookup依赖查找)。 DL由Martin Fowler 在2004年初的一篇论文中首次提出的。他总结:控制的什么被反转了?就是:获得依赖对象的方式反转了。
什么是IOC,什么又是DI,他们有什么区别?
一、IOC介绍
IOC是控制反转。
创建对象实例的控制权从调用者转移到IOC容器控制(之前的写法,由程序代码直接操控使用new关键字,现在IOC容器直接帮我们创建好了对象),实际就是你在xml文件控制,控制权的转移是所谓反转,侧重于原理。
二、DI介绍
DI是依赖注入
创建对象实例时,为这个对象注入属性值或其它对象实例,侧重于实现。
三、区别
1.它们是spring核心思想的不同方面的描述。
2.依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。
依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;
而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
IOC底层实现原理(Spring的核心)
概念:
IOC 是面向对象编程中的一种设计原则,IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。 是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方。
实现原理:
它是通过反射机制+工厂模式实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap( key: bean的id, value: 对象)中的类属性注入到类中。
控制反转就是:获得依赖对象的方式反转了。`
1、依赖注入发生的时间
(1).用户第一次通过getBean方法向IoC容索要Bean时,IoC容器触发依赖注入。
(2).当用户在Bean定义资源中为元素配置了lazy-init属性,即让容器在解析注册Bean定义时进行预实例化,触发依赖注入。
2.依赖注入实现在以下两个方法中:
(1).createBeanInstance:生成Bean所包含的java对象实例。
(2).populateBean :对Bean属性的依赖注入进行处理。
例:
<!--xml中--> <!-- 把对象交给Spring管理, 在配置文件配置 id: bean的标识符, 方便获取, 接口名第一个字母小写 class: 包名.类名, 实现类的 反射: Class.forName("spring01.hello.impl.HelloImpl") 得到HelloImpl的Class对象 newInstance(), 本质: 调用构造方法, 调用无参的构造方法 --> <bean id="hello" class="spring01.hello.impl.HelloImpl"></bean>