Spring启动流程
本文基于AnnotationConfigApplicationContext的方式启动,解析Spring启动的流程
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
一、构造方法
容器启动需要扫描BD(BeanDefinition),并创建BD,Spring将这两个功能分成了两个类,分别是
- AnnotatedBeanDefinitionReader,BD阅读器,用于根据Bean的元信息(比如类名、注解信息)创建BD
- ClassPathBeanDefinitionScanner,BD扫描器,用于根据指定路径扫描出符合条件的BD
this()构造方法中有两个关键方法
this.reader = new AnnotatedBeanDefinitionReader(this);
创建一个BD(BeanDefinition)阅读器
该构造方法需要传递一个BeanDefinitionRegistry注册器对象进去,我们可以看到这个注册器对象就是ApplicationContext本身
接着往下看,重点方法
这个方法是将spring内置的一些PostProcessor注册为BD
一共有6个内置的beanFactoryPostProcessor
- ConfigurationClassPostProcessor
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor(当项目中存在JSR250,即javax.annotation.Resource注解)
- PersistenceAnnotationBeanPostProcessor(当项目使用JPA)
- EventListenerMethodProcessor
- DefaultEventListenerFactory(这个比较特殊,不是beanFactoryPostProcessor)
registerPostProcessor方法只需要关注将PostProcessor注册为BD,简单理解为加入到DefaultListableBeanFactory中的beanDefinitionMap中。
this.scanner = new ClassPathBeanDefinitionScanner(this);
为给定的BeanFactory创建一个scanner
在scanner的构造方法中注册了一个默认的Filter,作用是包含所有@Component注解的类
二、register方法,将启动类注册为BD
使用上文new出的AnnotatedBeanDefinitionReader将启动类class
简单理解为解析类上的注解等元信息,并注册为BD
三、refresh方法
prepareBeanFactory方法
添加BeanPostProcessor:
- ApplicationContextAwareProcessor
- ApplicationListenerDetector
invokeBeanFactoryPostProcessors方法
顾名思义,执行所有BeanFactoryPostProcessor(BFPP),需要注意的是BeanDefinitionRegistryPostProcessor(BDFPP),BDFPP是BeanFactoryPostProcessor的子实现,相比于一般的BFPP,具有更高的优先级。
- 执行所有手动添加的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。
- 执行容器中实现
PriorityOrdered
的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。(提前实例化)(包含ConfigurationClassPostProcessor) - 执行容器中实现
Ordered
的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。(提前实例化) - 执行容器中剩下的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,在这过程中新创建出的实现PriorityOrdered或Ordered的新postProcessor可能不按顺序执行。
- 执行所有BeanDefinitionRegistryPostProcessor的
postProcessBeanFactory
方法。 - 执行所有BeanFactoryPostProcessor的
postProcessBeanFactory
方法(按照手动添加、PriorityOrdered、Ordered顺序)。
一般来说,在我们不手动添加BFPP的情况下,容器中只会存在ConfigurationClassPostProcessor这个特殊的BFPP(@Configuration注解的实现)