Spring Boot IoC
控制反转(英语:Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。
技术描述
Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式地用 new 创建 B 的对象。软件需要一个来自容器的对象,而容器自行建构对象和它的附属物。
采用依赖注入技术之后,A 的代码只需要定义一个 private 的B对象,不需要直接 new 来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。
实现方法
实现控制反转主要有两种方式:依赖注入和依赖查找。两者的区别在于,前者是被动的接收对象,在类A的实例创建过程中即创建了依赖的B对象,通过类型或名称来判断将不同的对象注入到不同的属性中,而后者是主动索取相应类型的对象,获得依赖对象的时间也可以在代码中自由控制。
依赖注入
在软件工程中,依赖注入(dependency injection)的意思为,给予调用方它所需要的事物。 “依赖”是指可被方法调用的事物。依赖注入形式下,调用方不再直接使用“依赖”,取而代之是“注入” 。“注入”是指将“依赖”传递给调用方的过程。在“注入”之后,调用方才会调用该“依赖”。传递依赖给调用方,而不是让让调用方直接获得依赖,这个是该设计的根本需求。
该设计的目的是为了分离关注点,分离调用方和依赖,从而提高可读性以及代码重用性。
依赖查找
依赖查找更加主动,在需要的时候通过调用框架提供的方法来获取对象,获取时需要提供相关的配置文件路径、key等信息来确定获取对象的状态
依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。
使用Java语言写成的程序在控制反转容器(Inversion of Control Container)里应用了控制反转
Spring IoC 容器
容器将创建对象,它们连接在一起,配置它们,并从创建到销毁管理他们的整个生命周期。在Spring容器使用依赖注入(DI)来管理组成应用程序的组件。这些对象被称为Spring Beans
容器获得其上的哪些对象进行实例化,配置和组装通过阅读提供的配置元数据的说明。配置元数据可以通过XML,Java注释或Java代码来表示。
Spring BeanFactory 容器
Spring ApplicationContext 容器
它比BeanFactory增加了一些额外的功能,例如与Spring的AOP的简单集成,消息资源处理(用于I18N),事件传播,Web应用程序的特定于应用程序层的上下文(例如WebApplicationContext)。
|
|
IOC容器初始化是由上文提到的refresh()方法来启动的,这个方法标志着IOC容器正式启动。
IOC容器初始化过程分为三个过程:
BeanDefinition的Resource定位过程。
这个Resource定位是指BeanDefinition资源定位,它由ResourceLoader通过统一的Resource接口完成。这个定位过程就是容器寻找数据的过程,就像水桶要装水首先需要找到水一样。
BeanDefinition的载入和解析过程。
这个过程就是根据上一步定位的Resource资源文件,把用户定义好的Bean表示成IOC容器内部的BeanDefinition数据结构。BeanDefinition实际就是POJO对象在IOC容器中的抽象,通过BeanDefinition定义数据结构,使IOC容器能够方便地对POJO对象也就是Bean进行管理。
向IOC容器注册BeanDefinition的过程。
这个过程是通过调用BeanDefinitionRegistry接口的实现来完成的,把载入过程生成的BeanDefinition向IOC容器注册。最终在IOC容器内部将BeanDefinition注入到一个HashMap中,IOC容器就是通过这个HashMap来持有这些BeanDefinition数据的。
源码分析
|
|
@EnableAspectJAutoProxy
注解会通过@Import注解快速导入AspectJAutoProxyRegistrar组件,这个组件会给容器中注册一个名为internalAutoProxyCreator的组件,internalAutoProxyCreator的组件的类型是AnnotationAwareAspectJAutoProxyCreator。
通过AnnotationAwareAspectJAutoProxyCreator继承树可以看出AnnotationAwareAspectJAutoProxyCreator继承了Aware接口和BeanPostProcessor接口,相当于AnnotationAwareAspectJAutoProxyCreator既是一个后置处理器,也是一个Aware接口(BeanFactoryAware)的实现类,可以自动装配。
- AbstractApplicationContext#refresh
- registerBeanPostProcessors
- AbstractBeanFactory#doGetBean
- AbstractAutowireCapableBeanFactory#doCreateBean(…)
- AbstractAutoProxyCreator#postProcessAfterInitialization
- AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean
- DefaultAopProxyFactory#createAopProxy(…)
|
|