前言
在Spring IOC 和 AOP 概览中,简要介绍了IOC容器和AOP,没有深入IOC容器Bean的实例化,此文承接上文深入分析Bean的实例化过程、生命周期。
Spring IOC的过程
Spring的IoC容器在实现控制反转和依赖注入的过程中,可以划分为两个阶段:
- 容器启动
- Bean实例化
容器启动的流程
- 容器启动阶段需要扫描 XML/注解/JavaConfig 中需要被Spring管理的Bean信息
- 将Bean信息封装成
BeanDefinition
并放入beanDefinitionMap
(key:beanName, value:BeanDefinition)中。1、2步骤完成元素据的加载,真实对象还未实例化 - 遍历
beanDefinitionMap
,执行BeanFactoryPostProcessor
(Bean工厂后置处理器)来对定义好的 Bean元数据进行获取或修改。
BeanFactoryPostProcessor 用于Bean实例化前修改Bean的元数据,如修改其中bean定义的某些属性,为bean定义增加其他信息等
完成上述三步后,容器启动完成,开始实例化对象。
Bean实例化过程
(1)根据 BeanDefinition
,利用反射选择合适的构造函数实例化对象。此步只创建对象,但对象属性还没有注入,如:UserService 对象依赖 UserDao,此时 UserService 中的 UserDao 还为null。
(2)注入对象相关属性
(3) 判断 Bean 是否实现了 Aware 相关接口。xxxAware 接口用于获取 xxx资源,如实现 BeanNameAware,则在接口方法能获取到 Bean 的名称。
演示如下(引用自:认识 Aware 接口,此文也介绍了其他一些Aware 接口)
@Component(value = "testBeanName2")
public class MyBeanName implements BeanNameAware {
@Override
public void setBeanName(String name) {
System.out.println("MyBeanName-setBeanName:"+name);
}
}
输出:
(4)调用 BeanPostProcessor
后置处理器的 before
方法。BeanPostProcessor
有两个方法,before
和 after
,BeanPostProcessor
是AOP实现的关键。
(5)执行 init 相关方法,如:@PostConstruct
标注的方法、实现的InitializingBean
接口方法、定义的 init-method 方法
(6)执行BeanPostProcessor
的 after
方法
上述步骤完成了Bean的实例化,Bean会一直保留在上下文容器中,直到容器被销毁。Bean销毁时,会调用配置的 destroy
方法。
总结
- Spring IOC 分为两个阶段:容器启动和Bean实例化阶段
- Spring Bean 的实例化和属性赋值(依赖注入)分两步完成,先实例再注入
- Spring Bean的生命周期中有很多的扩展接口:
Bean实例化前:可以通过BeanFactoryPostProcessor
修改BeanDefinition
中Bean的元数据。
Bean实例化后,初始化时:通过Aware
接口,获取资源
环绕Bean初始化过程:BeanPostProcessor
的 before 和 after 方法
初始化阶段:@PostConstruct等 init方法