文章目录
IoC容器加载流程
IoC容器加载流程可以分成两个步骤
- 将配置的各种 Bean 解析成为 BeanDefinition
- 遍历 BeanDefinition, 生产单例, 并缓存起来
注解形式的IoC容器加载流程
// 常见的写法, 其实AnnotationConfigApplicationContext还有一个传入basePackages的构造函数
// 如果传入的是包路径, 则通过BeanDefinitionScanner扫描, 找到候选组件将其封装成为BeanDefinition, 注册到容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Object bean = context.getBean("demo");
System.out.println(bean);
准备工作
初始化 AnnotationConfigApplicationContext 的时候, 会预先注册几个底层基础架构工具类, 他们以后置处理器的形式被注册, 在容器初始化流程中发光发热. 然后再注册配置类, 然后才是刷新容器
这些工具类中有两个非常重要
- ConfigurationClassPostProcessor: 配置类解析器, 负责解析配置类, 主要是解析配置类上的 @PropertySource, @ComponentScan, @Import, @ImportSelector 注解以及配置类中由 @Bean 注解标注的方法. 解析 @ComponentScan 的时候会扫描其指定的 basePackages 路径, 将标注有 @Component (@Repository, @Service, @Controller, @RestController 等含有 @Component 元注解, 也会被扫描到), @ManagedBean, @Named 注解的类也解析到
- AutowiredAnnotationBeanPostProcessor: 注解注入解析器, 负责解析 @Autowired
将配置的各种 Bean 解析成为 BeanDefinition
调用 refresh 的 invokeBeanFactoryPostProcessors 方法, 将自动或手动注册的各种 BeanFactoryPostProcessors (包括 BeanDefinitionRegistryPostProcessor) 按一定的顺序规则逐个调用其 postProcessBeanDefinitionRegistry 和 postProcessBeanFactory 方法
这里其实主要就是工具类 ConfigurationClassPostProcessor 在发光发热, 它解析到目前为止容器中所有 BeanDefinition 中的配置类, 将相关的组件候选全都注册成为 BeanDefinition
遍历 BeanDefinition, 生产单例, 并缓存起来
调用 refresh 的 finishBeanFactoryInitialization 方法, 遍历 beanNames, 拿到对应 beanName 的 BeanDefinition, 符合生产条件(非抽象&是单例&非懒加载)的都调用 getBean(beanName) 来生产 Bean, 并缓存到一级缓存(单例池)中
Bean 生产步骤
Bean 的创建可以分为三个步骤
- 实例化: 就是通过工厂(@Bean)或反射(无参反射, 有参构造函数反射)等完成 Bean 从无到有的第一步. ObjectBean 是不是在这里生效?
- 填充属性: Bean 如果有 @Autowired / @Value 注解标注的属性, 则需要做自动填充, 主要由 AutowiredAnnotationBeanPostProcessor 来完成
- 初始化: 调用各种 Aware 的相关属性注入方法, BeanPostProcessor 的 postProcessBeforeInitialization 方法 (包括 @PostConstruct 指定的初始化方法), InitializingBean 的 afterPropertiesSet 方法, 自定义的 init-method 方法, BeanPostProcessor 的 postProcessAfterInitialization 方法
生产完成之后, 将该 Bean 缓存到一级缓存(单例池)中
Bean 的生命周期接口调用
BeanFactory 的实现应该尽可能支持标准 Bean 生命周期接口. 全套初始化方法及其标准顺序如下
- BeanNameAware 的 setBeanName
- BeanClassLoaderAware 的 setBeanClassLoader
- BeanFactoryAware 的 setBeanFactory
- EnvironmentAware 的 setEnvironment
- EmbeddedValueResolverAware 的 setEmbeddedValueResolver
- ResourceLoaderAware 的 setResourceLoader (仅在 Application Context 中适用)
- ApplicationEventPublisherAware 的 setApplicationEventPublisher (仅在 Application Context 中适用)
- MessageSourceAware 的 setMessageSource (仅在 Application Context 中适用)
- ApplicationContextAware 的 setApplicationContext (仅在 Application Context 中适用)
- ServletContextAware 的 setServletContext (仅在 Web Application Context 中适用) (ServletContext 可能是指在 Servlet 容器中运行的每一个应用)
- BeanPostProcessors 的 postProcessBeforeInitialization, 其中包括 @PostConstruct 的处理与标注方法的调用
- InitializingBean 的 afterPropertiesSet
- 自定义的 init-method 方法
- BeanPostProcessors 的 postProcessAfterInitialization
BeanNameAware, BeanClassLoaderAware, BeanFactoryAware 是在 Bean 初始化方法 initializeBean 里面调用的
EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware 是在 ApplicationContextAwareProcessor 这个 BeanPostProcessor 里面的 postProcessBeforeInitiolization 方法调用的
// 在 BeanPostProcessors 的 postProcessBeforeInitialization 中, InitDestroyAnnotationBeanPostProcessor会处理 @PostConstruct 注解, 会调用被该注解标注的方法, CommonAnnotationBeanPostProcessor 是 reader 注册的创世纪处理器之一
class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
到这一步, bean已经生产好了, 它们将一直驻留在 ApplicatonContext 中, 直到该 ApplicatonContext 被销毁
在关闭 BeanFactory 时, 以下生命周期方法适用
- DestructionAwareBeanPostProcessors 的 postProcessBeforeDestruction, 其中包括 @PreDestroy 的处理与标注方法的调用
- DisposableBean 的 destroy
- 自定义的 destroy-method 方法