- 一、引言
- 二、new AnnotationConfigApplicationContext()
- 三、register(AppConfig.class)
- 四、refresh()
经过前面一系列文章对Spring
的源码分析,终于知道Spring
容器启动过程中做了哪些事情,下面就来最这个过程进行宏观上的总结。测试代码只需三行,就可以完成Spring
容器的启动和扫描工作,下面对三行代码都做了哪些操作进行大概描述。
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.register(AppConfig.class);
ac.refresh();
}
二、new AnnotationConfigApplicationContext()
创建AnnotationConfigApplicationContext
容器,在这个过程中会做3件事情。
AnnotationConfigApplicationContext ac= new AnnotationConfigApplicationContext();
-
这里会调用父类(
GenericApplicationContext
)的构造函数,创建一个DefaultListableBeanFactory
容器工厂 -
创建一个
AnnotatedBeanDefinitionReader
读取器,在这过程中会向Spring
容器中填加了6个Spring
的后置处理器:BeanFactoryPostProcessor
、BeanPostProcessor
org.springframework.context.annotation.internalConfigurationAnnotationProcessor—>(BeanFactoryPostProcessor)
org.springframework.context.annotation.internalAutowiredAnnotationProcessor—>(BeanPostProcessor)
org.springframework.context.annotation.internalRequiredAnnotationProcessor—>(BeanPostProcessor)
org.springframework.context.annotation.internalCommonAnnotationProcessor—>(BeanPostProcessor)
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
-
创建一个
ClassPathBeanDefinitionScanner
扫描器,这个扫描器可以用来扫描包或者类,将扫描到的类转换成BeanDefinition
,但是实际上完成我们扫描包工作并不是这个scanner
对象来完成的,而是Spring
自己new
的一个ClassPathBeanDefinitionScanner
注册一个配置类,其实这步操作可以和上面创建容器操作合为一步。
annotationConfigApplicationContext.register(AppConfig.class);
- 将配置类转化为一个
BeanDefinition
,给BeanDefinition
里面的属性确定值
这个容器刷新方法非常非常非常重要!!!也最难理解,总结不对的地方,请指正出来。
annotationConfigApplicationContext.refresh();
public void refresh() throws BeansException, IllegalStateException {
// 准备工作,包括设置启动时间,是否激活标识位,初始化属性源(property source)配置
prepareRefresh();
// 返回一个factory 为什么需要返回一个工厂? 因为要对工厂进行初始化
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备工厂
prepareBeanFactory(beanFactory);
// 这个方法在当前版本的spring是没用任何代码的,可能spring期待在后面的版本中去扩展吧
postProcessBeanFactory(beanFactory);
// 调用BeanFactoryPostProcessors的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
//-------------------到此spring工厂完成创建工作--------------------------
// 注册BeanPostProcessor后置处理器
registerBeanPostProcessors(beanFactory);
initMessageSource();
// 初始化应用事件广播器
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
每个方法做了哪些工作,下面逐一总结。
-
prepareRefresh()
:- 准备工作,包括设置启动时间,是否激活标识位,初始化属性源(
property source
)配置
- 准备工作,包括设置启动时间,是否激活标识位,初始化属性源(
-
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
-
prepareBeanFactory(beanFactory)
- 添加一个后置管理器:
ApplicationContextAwareProcessor
,能够在Bean
中获得到各种*Aware
(Aware
都有其作用),重要!!!【直接创建添加到BeanPostProcessors
中】 - 添加一个后置管理器:
ApplicationListenerDetector
,【直接创建添加到BeanPostProcessors
中】 - 向
singletonObjects
中添加了systemEnvironment
- 向
singletonObjects
中添加了environment
- 添加一个后置管理器:
-
向
singletonObjects
中添加了systemProperties
-
postProcessBeanFactory(beanFactory)
- 这个方法在当前版本的
Spring
是没用任何代码的,可能Spring
期待在后面的版本中去扩展吧
- 这个方法在当前版本的
-
invokeBeanFactoryPostProcessors(beanFactory)
调用BeanFactoryPostProcessors的后置处理器,设置执行自定义的ProcessorBeanFactory和Spring内部自己定义的
- 执行程序员自定义(手动add)的实现
BeanDefinitionRegistryPostProcessor
接口中的postProcessBeanDefinitionRegistry()
【程序员自己手动add】 - 执行
Spring
内部自己实现了BeanDefinitionRegistryPostProcessor
接口的postProcessBeanDefinitionRegistry()
—>【上面添加的6个中,只有这个ConfigurationClassPostProcessor
,该类中完成了Spring
的扫描工作】 - 执行程序员自己实现
BeanDefinitionRegistryPostProcessor
接口的类postProcessBeanDefinitionRegistry()
,被扫描进来的【用注解@Component
修饰】 - 执行
BeanFactoryPostProcessor
的子类BeanDefinitionRegistryPostProcessor
中postProcessBeanFactory()
【Spring
内部自己添加、或者扫描到的】 - 执行程序员自定义(手动add)的
BeanFactoryPostProcessor
的中postProcessBeanFactory()
- 执行
Spring
内部自己实现了BeanFactoryPostProcessor
接口或扫描到实现该接口类中的postProcessBeanFactory()
- 执行程序员自定义(手动add)的实现
------------------------------------到此Spring工厂完成创建工作------------------------------------
-
registerBeanPostProcessors(beanFactory)
注册BeanPostProcessor后置处理器
- 实例化所有
BeanPostProcessor
,放入到singletonObjects
中和beanPostProcessors
中【所有包括,Spring
一开始自己添加的,程序员自己手动add
,包扫描到的三种情况】
- 实例化所有
-
initMessageSource()
-
实例化一个消息源,放入到
singletonObjects
中 -
initApplicationEventMulticaster();
初始化应用事件广播器
实例化一个事件广播器
applicationEventMulticaster
,放入到singletonObjects
中 -
onRefresh()
在SpringBoot中,这个方法中创建了Tomcat
-
registerListeners()
-
将监听器添加到
applicationEventMulticaster
事件广播器中 -
finishBeanFactoryInitialization(beanFactory)
实例化所有的单例的非懒加载的Bean
- 遍历
this.beanDefinitionNames
,根据beanName
获取BeanDefinition
- 从
singletonObjects
中获取bean
,如果不为空直接返回,不再进行初始化工作 - 判断是不是
FactoryBean
,如果是,则直接创建FactoryBean
,如果不是,则创建普通Bean
【此处要注意获取FactoryBean
中真实对象的情况,此处要注意!!!!】- 如果给定
Bean
的定义是子Bean
定义,则通过与父Bean
合并,返回给定顶级Bean
的RootBeanDefinition
- 获取所依赖的
Bean
,保证对当前Bean
所依赖的Bean
进行初始化【此处是递归调用getBean()
方法】 createBean()
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
【第一次调用BeanPostProcessor
后置处理器】doCreateBean()
-
createBeanInstance()
- 使用适当的实例化策略,为指定的bean创建一个新实例:工厂方法、构造函数自动装配,简单实例化
SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors()
【第二次调用BeanPostProcessor
后置处理器】- 创建Bean实例
-
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition()
【第三次调用BeanPostProcessor
后置处理器】 -
SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference()
【第四次调用BeanPostProcessor
后置处理器】 -
populateBean()
设置属性InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
【第五次调用BeanPostProcessor
后置处理器】InstantiationAwareBeanPostProcessor#postProcessPropertyValues()
【第六次调用BeanPostProcessor
后置处理器】initializeBean()
初始化invokeAwareMethods()
判断Bean
是不是实现了Aware
接口BeanPostProcessor#postProcessBeforeInitialization()
【第七次调用BeanPostProcessor
后置处理器】invokeInitMethods()
调用初始化方法- 实现
InitializingBean
接口的话,调用afterPropertiesSet()
- 有
init-method
方法的话,调用此自定义方法
- 实现
BeanPostProcessor#postProcessAfterInitialization()
【第八次调用BeanPostProcessor
后置处理器】
-
- 如果给定
- 从
- 遍历
-
finishRefresh()