Spring IOC 容器 Bean 加载过程
Spring 对于我们所有的类对象进行了统一抽象,抽象为 BeanDefinition ,即 Bean 的定义,其中定义了类的全限定类名、加载机制、初始化方式、作用域等信息,用于对我们要自动装配的类进行生成。
Spring 会读取我们需要装配的类的元数据信息,将其转换注册为 BeanDefinition ,元数据 MateData 即指类的字符文本表示,将其放入Bean 定义的容器中,这个过程经历了:
- 读取磁盘中的元数据 BeanDefinitionReader
- 扫描需要装配的类 BeanDefinitionScanner
- 注册 BeanDefinition 到 BeanDefinition 容器中 (Map) BeanDefinitionRegister
在 Bean 定义注册完成后,类加载前,可以通过实现 Spring 提供的拓展点接口进行 BeanDefinition 的修改的添加,比如:
- 实现 BeanFactoryPostProcessor 的 postProcessBeanFactory 获取已注册的 Bean 定义并进行修改
- 实现 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法添加 Bean 定义
有了 BeanDefinition 就可以通过 BeanFactory 对应加载实例化 Bean ,Bean 的加载经过了以下过程:
- 通过反射实例化 Bean
- 对类的属性赋值如 @Value 、 @Autowear 等
- 类的初始化,执行初始化开始方法(如果有)
@Component
public class MyBean {
public void init(){
// 根据类名获取并在初始化时执行
System.out.println("MyBean initialization logic");
}
public void destroy(){
System.out.println("MyBean destruction logic");
}
}
- 最终放入单例缓存池。供后续使用
在整个加载过程中 Spring 在各个阶段执行前后提供了拓展点,如 :
- InstantiationAwareBeanPostProcessor:在Bean实例化之前执行拦截方法。(Aop 即通过该实现拓展点来完成的)
- BeanPostProcessor:在Bean实例化之后,执行拦截方法。
以及各种各样的发现 Aware 如:
- ApplicationContextAware:让Bean获得当前Spring容器的ApplicationContext实例。
- BeanNameAware:让Bean获得它在Spring容器中的Bean名称。
- BeanClassLoaderAware:让Bean获得它在Spring容器中的ClassLoader实例。
- BeanFactoryAware:让Bean获得当前Spring容器的BeanFactory实例。
此时 Bean 就到达了最终可用状态。