Spring IOC实现原理解析

IOC

IOC即DI,控制反转与依赖注入。表示的概念都是将对象自身从其依赖关系的管理中解放出来,将这个管理工作的责任交给第三方来完成。在Spring中,这个第三方就是IOC容器:基础版的BeanFactory和升级版的ApplicationContext。IOC容器全面接手了对象依赖关系图的管理工作。

管理工作主要分为两大部分:元数据信息的准备和对象关系图的正式建立。

元数据信息

元数据信息主要是指BeanDefinition,BeanDefinition是对Bean定义的描述数据结构,是IOC容器的关键数据结构。元数据信息的准备过程主要有三步:

  1. 定位:Resource资源定位(文件、路径、网络等,是BeanDefinition的资源定位)
  2. 读取与转化:通过各类Reader和Parser将Resource解析为BeanDefinition数据结构
  3. 注册:将BeanDefinition注册到IOC容器中的HashMap中去

对象依赖关系图的建立

关系图的建立大体有三步:

  1. 实例化Bean
  2. 注入设置Bean的属性
  3. Bean的初始化

IOC容器持有了BeanDefinition后,就可以根据BeanDefinition中的信息在实例化Bean时逐步建立起该Bean的依赖关系图了。这一步与JVM中的类加载中解析阶段有些神似,将BeanDefinition中的“符号引用”解析为实例引用。

建立工作通过getBean()方法触发,会首先实例化该Bean(createBean()方法),然后会对该Bean的属性进行设置(populateBean()方法),此时会向IOC容器再次getBean以获取属性值,依次类推,递归调用,最终建立对象依赖关系图。同时对于对象间的depends-on依赖(顺序依赖,如A依赖B的数据,但是B却由C进行设置,此时A depends-on C)也进行递归的准备。在这个过程中Bean的实例化与依赖关系图的建立是交替扩散式进行的。在Bean的属性均注入完毕以后,调用Bean的初始化方法对Bean进行初始化(initializeBean()方法)。

在IOC中,Bean的实例化有两种方式:一种是通过反射的构造函数实例化;一种是通过CGLIB实例化Proxy。通过CGLIB实例化的通常是设置了BeanPostProcessor,或者有lookup method/replace method,需要通过代理技术来实现。

对于Bean属性的注入是通过反射技术来实现的。

Bean生命周期

Spring IOC容器在对Bean的生命周期进行管理时提供了Bean生命周期各个时间点的回调。
Bean的生命周期:

  1. Bean实例的创建(getBean->createBean)
  2. 为Bean实例设置属性(populateBean)
  3. 初始化Bean(initializeBean)
  4. Bean 被应用使用
  5. 容器关闭时,Bean销毁(destoryMethod)

其中Bean的初始化主要依次做了4件事:

  1. 设定Bean对容器的感知(一系列Aware接口)
  2. BeanPostProcessorsBeforeInitialization()方法
  3. 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法,如果指定了init-method,调用init-method
  4. BeanPostProcessorsAfterInitialization()方法

Spring技术内幕

猜你喜欢

转载自blog.csdn.net/john_lw/article/details/78931190