Spring启动流程

本文基于AnnotationConfigApplicationContext的方式启动,解析Spring启动的流程
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

一、构造方法

容器启动需要扫描BD(BeanDefinition),并创建BD,Spring将这两个功能分成了两个类,分别是

  • AnnotatedBeanDefinitionReader,BD阅读器,用于根据Bean的元信息(比如类名、注解信息)创建BD
  • ClassPathBeanDefinitionScanner,BD扫描器,用于根据指定路径扫描出符合条件的BD


this()构造方法中有两个关键方法

  1. this.reader = new AnnotatedBeanDefinitionReader(this); 创建一个BD(BeanDefinition)阅读器
    该构造方法需要传递一个BeanDefinitionRegistry注册器对象进去,我们可以看到这个注册器对象就是ApplicationContext本身

接着往下看,重点方法
image
这个方法是将spring内置的一些PostProcessor注册为BD
image
一共有6个内置的beanFactoryPostProcessor

  • ConfigurationClassPostProcessor
  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor(当项目中存在JSR250,即javax.annotation.Resource注解)
  • PersistenceAnnotationBeanPostProcessor(当项目使用JPA)
  • EventListenerMethodProcessor
  • DefaultEventListenerFactory(这个比较特殊,不是beanFactoryPostProcessor)

registerPostProcessor方法只需要关注将PostProcessor注册为BD,简单理解为加入到DefaultListableBeanFactory中的beanDefinitionMap中。

  1. this.scanner = new ClassPathBeanDefinitionScanner(this);为给定的BeanFactory创建一个scanner

在scanner的构造方法中注册了一个默认的Filter,作用是包含所有@Component注解的类

image

二、register方法,将启动类注册为BD

使用上文new出的AnnotatedBeanDefinitionReader将启动类class
简单理解为解析类上的注解等元信息,并注册为BD

三、refresh方法

prepareBeanFactory方法

添加BeanPostProcessor:

  • ApplicationContextAwareProcessor
  • ApplicationListenerDetector

invokeBeanFactoryPostProcessors方法

顾名思义,执行所有BeanFactoryPostProcessor(BFPP),需要注意的是BeanDefinitionRegistryPostProcessor(BDFPP),BDFPP是BeanFactoryPostProcessor的子实现,相比于一般的BFPP,具有更高的优先级。

  1. 执行所有手动添加的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。
  2. 执行容器中实现PriorityOrdered的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。(提前实例化)(包含ConfigurationClassPostProcessor)
  3. 执行容器中实现Ordered的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。(提前实例化)
  4. 执行容器中剩下的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,在这过程中新创建出的实现PriorityOrdered或Ordered的新postProcessor可能不按顺序执行。
  5. 执行所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法。
  6. 执行所有BeanFactoryPostProcessor的postProcessBeanFactory方法(按照手动添加、PriorityOrdered、Ordered顺序)。
    一般来说,在我们不手动添加BFPP的情况下,容器中只会存在ConfigurationClassPostProcessor这个特殊的BFPP(@Configuration注解的实现)

【ConfigurationClassPostProcessor】源码,@Configuratio原理

posted @ 2024-05-11 10:38  小白白白白白白白白白  阅读(12)  评论(0编辑  收藏  举报