Spring容器启动相关概念

177 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

大纲

  • 启动总览
  • BeanFactoryPostProcessor
  • BeanDefinitionRegistryPostProcessor
  • refresh( )
  • Lifecycle

1.Spring启动流程总览

1.创建BeanFactory工厂对象。

2.解析启动类/配置类信息,构造BeanDefinition对象,并注册到BeanFactory中。

解析@ComponentScan完成扫描、解析@Import、解析@Bean等。

3.初始化国际化MessageSource对象、初始化事件机制对象ApplicationEventMulticaster对象。

4.将用户定义的ApplicationListener对象注册到ApplicationContext中。

5.创建非懒加载的单例Bean,创建完后放入BeanFactory的单例池singletonObjects的Map中。

5.1 生成Spring自己内部的BeanPostProcessor对象,并注册到BeanFactory中
        - AutowiredAnnotationBeanPostProcessor:处理@Autowired@Value注解
        - CommonAnnotationBeanPostProcessor:处理@Resource@PostConstruct@PreDestroy注解
        - ApplicationContextAwareProcessor:处理容器的各种Aware回调。
5.2 寻找用户自定义的BeanPostProcessor对象,并注册到BeanFactory中

6.触发Lifecycle实现类的start( ),用户可自定义实现Lifecycle覆盖其start( )、stop( )、 isRunning( )等获取容器生命周期某个阶段的方法。

7.发布ContextRefreshedEvent事件,订阅了该事件的方法会被回调通知。

2.BeanFactoryPostProcessor的作用

和BeanPostProcessor类似,BeanFactoryBeanPostProcessor是针对BeanFactory加工的后置处理器。 BeanFactoryPostProcessor # postProcessBeanFactory( )的入参是容器对象。 BeanFactoryPostProcessor发生在Spring启动后,创建单例Bean之前触发,所以可以进行对容器的一些操作,例如获取容器里的BeanDefinition然后,对BeanDefinition进行操作、设置值等。

3.BeanDefinitionRegistryPostProcessor的作用

因为ConfigurableListableBeanFactory对象是没有注册BeanDefinition的能力,只有获取BeanDefinition的能力,所以BeanDefinitionRegistryPostProcessor的作用就是弥补BeanFactoryPostProcessor无法注册BeanDefinition的短板。

4.refresh( )方法总览

  1. 创建AnnotationConfigApplicationContext时,父类GenericApplicationContext构造触发创建一个Bean工厂,就是耳熟能详的DefaultListableBeanFactory
  2. 构建BeanDefinitionReader,添加基础的PostProcessor,例如dependency、@Order注解、Order接口。
  3. 包扫描、构建BeanDefinition、注册BeanDefinition
  4. 设置ResourceLoader、Environment。基础设置完毕,注册配置类为BeanDefinition并注册。
  5. refresh( )方法的触发调用,并记录启动时间,允许Envionment对象设置外部的变量。
  6. 设置BeanFactory的类加载器、注册ApplicationContextAwareProcessor方便后续回调EnvironmentAware、AplicationEventPublisherAware等回调。
  7. 执行BeanFactoryPostProcessor。
  8. 实例化非懒加载的单例Bean,完成BeanFactory的初始化。
  9. 调用LifecycleProcessor的onRefresh( )方法。
  10. 发布ContextRefreshedEvent事件。