- 一、引言
- 二、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、BeanPostProcessororg.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()
