Spring启动流程
【ClassPathXmlApplicationContext】xml方式启动为例
1. 初始化参数
spring会把容器接口的第一个参数设置为configLocations,作为基础的配置文件绑定,随后调用refresh方法
$1=ClassPathXmlApplicationContext
$1#super(parent);
//把传入的配置文件配置给Context本身的configLocations属性
$1# this.setConfigLocations("传入的配置文件");
if (refresh) {
$1# this.refresh();//执行Context的刷新操作
}
2. 初始化及加载的全流程
$1=AbstractApplicationContext
$1#refresh()
synchronized($1# this.startupShutdownMonitor) {
//刷新前的预处理,准备上下文的刷新
$1# this.prepareRefresh()
//通知子类刷新内部的BeanFactory,获取BeanFactory,类型为ConfigurableListableBeanFactory
$1# this.obtainFreshBeanFactory()=@1
//BeanFactory的预准备
$1# this.prepareBeanFactory(@1)
try {
//允许上下文子类对BeanFactory进行后置处理,BeanFactory准备完成后置处理,【模板方法】
$1# this.postProcessBeanFactory(@1)
//调用上下文中注册为工厂处理器的Bean,BeanFactoryPostProcessor的处理调用
$1# this.invokeBeanFactoryPostProcessors(@1)
//实例化注册BeanPostProcessor(Bean创建的拦截处理器),在创建bean的前后执行
$1# this.registerBeanPostProcessors(@1)
//初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
$1# this.initMessageSource()
//初始化事件派发器
$1# this.initApplicationEventMulticaster()
//子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat等WEB服务器,【模板方法】
$1# this.onRefresh()
//注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean
$1# this.registerListeners()
//BeanFactory内容初始化
$1# this.finishBeanFactoryInitialization(@1)
//完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法
$1# this.finishRefresh()
} catch (BeansException var9) {
$1# this.destroyBeans();
$1# this.cancelRefresh(var9);
throw var9;
} finally {
$1# this.resetCommonCaches();
}
}
2.1 this.prepareRefresh() 刷新前的预处理
实现在真正做refresh操作之前需要准备做的事情:
- 设置Spring容器的启动时间
- 开启活跃状态
- 撤销关闭状态
- 预留【initPropertySources()】给子类留下配置文件加载的【模板方法】
- 看到springboot或者Springmvc这里需要注意看
- 验证环境信息里一些必须存在的属性(目前没看到有什么作用)
- 初始化或者传递获取应用事件的处理
- 看到springboot或者Springmvc这里需要注意看
- 看到springboot的时候这里会有初始的值
$1=AbstractApplicationContext
$1#prepareRefresh();
$1#initPropertySources();//钩子方法
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet<>();
2.2 this.obtainFreshBeanFactory() 获取BeanFactory
获取BeanFactory,默认实现是DefaultListableBeanFactory,这里获取的BeanFactory已经有了BD
- 先判断是否存在BeanFactory,存在清空所有的引用对象(各级缓存和各种map)
- 实例化 DefaultListableBeanFactory
- 给BeanFactory设置序列化id
- 定制BeanFactory的一些属性(是否覆盖、是否允许循环依赖)
- 加载应用中的BeanDefinitions
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions自定义解析
- 这里的configLocations解析,即xml解析就是dom4j啥的,主要可以看下注解类的解析
$1=AbstractApplicationContext
$1#obtainFreshBeanFactory()
$2=AbstractRefreshableApplicationContext#refreshBeanFactory//$2是$1的子类
$2#refreshBeanFactory()
// 定制bean工厂的一些属性
$2#customizeBeanFactory()
// 加载应用中的BeanDefinitions
$2#loadBeanDefinitions()
2.3 this.prepareBeanFactory() BeanFactory预处理
BeanFactory的预准备工作,对BeanFactory进行一些设置,比如context的类加载器等
设置Bean的类加载器
设置Bean的表达式解析器
设置资源编辑注册
添加一个BeanPostProcessor
ApplicationContextAwareProcessor.class
Spring重要扩展点:Aware相关的出发都来自于这个类
设置加载豁免的类型
- EnvironmentAware
- EmbeddedValueResolverAware
- ResourceLoaderAware
- ApplicationEventPublisherAware
- MessageSourceAware
- ApplicationContextAware
注册BeanFactory接口的Bean为自身
注册ResourceLoader接口的Bean为自身
注册ApplicationEventPublisher接口的Bean为自身
注册ApplicationContext接口的Bean为自身
添加一个BeanPostProcessor
ApplicationListenerDetector.class
Spring重要扩展点:事件相关的注册基本都来自于这个类
在容器处理之前先注册environment的单例
在容器处理之前先注册systemProperties的单例
在容器处理之前先注册systemEnvironment的单例
$1=AbstractApplicationContext
$1#prepareBeanFactory()
$2=ConfigurableListableBeanFactory@1
$3#addBeanPostProcessor(new ApplicationContextAwareProcessor(@1));
$3#addBeanPostProcessor(new ApplicationListenerDetector(@1));
2.4 this.postProcessBeanFactory(@1) BeanFactory创建后预留的模板方法
这个方法时留给子类实现的模板方法,作用时可以在BeanFactory准备完成后做处理,此时已经有初始化BD的BeanFactory了
2.5 this.invokeBeanFactoryPostProcessors(@1) 执行BeanFactoryPostProcessor
这个步骤主要触发BeanDefinitionRegistryPostProcessor(BeanFactoryPostProcessor)相关的内容,先调用BeanDefinitionRegistryPostProcessor在调用BeanFactoryPostProcessor,不然BD修改了,就和BeanFactory不一致了
首先看BeanFactory是不是一个BeanDefinitionRegistry
如果是的话[BeanDefinitionRegistryPostProcessor->BeanFactoryPostProcessor执行点postProcessBeanDefinitionRegistry,postProcessBeanFactory]
- 调用#postProcessBeanDefinitionRegistry()的顺序和内容
- 先执行上下文中给其设置的BeanDefinitionRegistryPostProcessor
- 如果实现BeanDefinitionRegistryPostProcessor直接调用
- 未实现BeanDefinitionRegistryPostProcessor加入到 regularPostProcessors
- 执行同时实现BeanDefinitionRegistryPostProcessor、PriorityOrdered的处理
- 执行同时实现BeanDefinitionRegistryPostProcessor、Ordered的处理
- 最后执行仅实现BeanDefinitionRegistryPostProcessor的处理
- 调用#postProcessBeanFactory()的顺序和内容
- 以上所有的实现BeanDefinitionRegistryPostProcessor的处理
- regularPostProcessors中实现BeanFactoryPostProcessor的处理
如果不是BeanDefinitionRegistry[BeanFactoryPostProcessor执行点postProcessBeanFactory]
- 执行上下文中给其设置的BeanFactoryPostProcessor调用#postProcessBeanFactory()
调用#postProcessBeanFactory()的顺序和内容
- 干刚刚执行过的全部排除,防止二次执行
- 执行同时实现BeanFactoryPostProcessor、PriorityOrdered的处理
- 执行同时实现BeanFactoryPostProcessor、Ordered的处理
- 最后执行仅实现BeanFactoryPostProcessor的处理
添加一个BeanPostProcessor
LoadTimeWeaverAwareProcessor.class
Spring重要节点:AOP相关内容,实现了BeanPostProcessor
$1=AbstractApplicationContext
$1#invokeBeanFactoryPostProcessors()
$2=PostProcessorRegistrationDelegate
$2#invokeBeanFactoryPostProcessors()
...
//调用#postProcessBeanDefinitionRegistry()
$2#invokeBeanDefinitionRegistryPostProcessors()
...
//调用#postProcessBeanFactory()
$2#invokeBeanFactoryPostProcessors()
$3=ConfigurableListableBeanFactory@1
$3#addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
2.6 this.registerBeanPostProcessors(@1) 注册BeanPostProcessor
这个步骤主要注册MergedBeanDefinitionPostProcessor(BeanPostProcessor)相关的内容
添加一个BeanPostProcessor
BeanPostProcessorChecker.class
Spring重要校验:判断BeanPostProcessor相关,没看明白
注册流程
- 注册同时实现BeanPostProcessor、PriorityOrdered的处理
- 把其中的MergedBeanDefinitionPostProcessor放到internalPostProcessors
- 注册同时实现BeanPostProcessor、Ordered的处理
- 注册仅实现BeanPostProcessor的处理
- 注册internalPostProcessors中的MergedBeanDefinitionPostProcessor(其实之前注册过了,重新注册是为了排序,保证MergedBeanDefinitionPostProcessor处于列表的后面)
添加一个BeanPostProcessor
ApplicationListenerDetector.class
和上面注册的是一样的这里是为了调整顺序
注册结果beanPostProcessors列表中
- 同时实现BeanPostProcessor、PriorityOrdered
- 同时实现BeanPostProcessor、Ordered
- 仅实现BeanPostProcessor
- 同时实现MergedBeanDefinitionPostProcessor、PriorityOrdered
- 同时实现MergedBeanDefinitionPostProcessor、Ordered
- 仅实现MergedBeanDefinitionPostProcessor
- ApplicationListenerDetector(保证列尾是这个事件注册)
分析
:
- PriorityOrdered的BeanPostProcessor在实例化时不会被其他BeanPostProcessor执行
- Ordered的BeanPostProcessor在实例化时不会被仅有BeanPostProcessor执行
$1=AbstractApplicationContext
$1#invokeBeanFactoryPostProcessors()
$2=PostProcessorRegistrationDelegate
//这里未来需要看,不知道为啥要这么做
beanFactory.addBeanPostProcessor( );
2.7 this.initMessageSource() 没有看
感觉意义不大,暂时不看
2.8 this.initApplicationEventMulticaster() 初始化初始化事件派发器
实例化事件派发器
- 如果此时容器中已经有满足下面条件的那就使用那个bean,注意,此时容器没有实例化Bean需要自己单独处理
- 名为 applicationEventMulticaster
- 类型为ApplicationEventMulticaster.class
- 如果不满足上面的条件,那直接new了一个默认的
- SimpleApplicationEventMulticaster.class
2.9 this.onRefresh() 特定上下文刷新
这里是在执行Bean的实例化步骤之前,子类可以重写这个方法,在容器刷新的时候可以自定义逻辑;如Springboot使用这里创建Tomcat等WEB服务器,是【模板方法】
2.10 this.registerListeners() 注册应用的监听器
注册应用的监听器并把earlyApplicationEvents中的事件发布
- 先把容器中预先设置的事件监听器注册到事件派发器
- 这里对事件监听器的处理有一些特殊,会判断是否是AOP的代理对象
- 如果是AOP的代理对象还需要判断没看明白判断啥
- 再把BeanFactory中的事件监听器注册到事件派发器
- 最后发布earlyApplicationEvents预先添加的事件,这里默认是空的
2.11 this.finishBeanFactoryInitialization(@1) 初始化所有非懒加载的Bean
初始化所有非懒加载的Bean
实例化实现了LoadTimeWeaverAware的类,保证所有LoadTimeWeaverAware的Bean都在此时初始化出来
停用临时类加载器启用在哪没注意
冻结容器中的BD数量和名字
实例化所有非lazy单例进行遍历
获取mergedBD(RootBeanDefinition)
判断是不是抽象、单例、懒加载
获取Bean
获取Bean,如果是FB无限往里获取直到没有$
从singleobjects获取对应Bean
一级缓存完全体singletonObjects
二级缓存光杆实例earlySingletonObjects 如果这个类处于创建中才查二三级缓存
三级缓存初始工厂singletonFactories判断Bean是不是正在创建中,是就报错
设置Bean 为创建中
获得mergedBD(RootBeanDefinition)
获取依赖的Bean并遍历获取Bean
实例化这个Bean
尝试从singleobjects取
回调Spring标志的SF
反射Bean的Class
这里面涉及一个变量,BD的beanclass,这个变量声明的Object,在没进这步之前都是String,进了之后会解析成Class类型
[InstantiationAwareBeanPostProcessor->BeanPostProcessor执行点postProcessBeforeInstantiation]
InstantiationAwareBeanPostProcessor(实现此接口的类在进入createbean的过程中未创建bean的时候,此时已经有了Bean的class,这时候返回的Obj就是Bean)
创建Bean
- 获取BeanWrapped
- [MergedBeanDefinitionPostProcessor->BeanPostProcessor执行点postProcessMergedBeanDefinition]
把刚刚的Bean使用lamba存入singletonFactories、
getEarlyBeanReference
感觉是通过这个获取Bean,如果直接是完全体就获取,中间体就进if
给Bean添加属性
[InstantiationAwareBeanPostProcessor->BeanPostProcessor执行点postProcessAfterInstantiation]
[InstantiationAwareBeanPostProcessor->BeanPostProcessor执行点postProcessProperties]
调用此方法可以对注入的内容进行修改
把Bean的属性存入BW
初始化Bean
- 调用Aware
- [BeanNameAware->Aware执行点setBeanName]
- [BeanClassLoaderAware->Aware执行点]setBeanClassLoader
- [BeanFactoryAware->Aware执行点setBeanFactory]
- [BeanPostProcessor执行点postProcessBeforeInitialization]
- 有一个关键类ApplicationContextAwareProcessor会调起其他执行点
- [EnvironmentAware->Aware执行点setEnvironment]
- [EmbeddedValueResolverAware->Aware执行点setEmbeddedValueResolver]
- [ResourceLoaderAware->Aware执行点setResourceLoader]
- [ApplicationEventPublisherAware->Aware执行点setApplicationEventPublisher]
- [MessageSourceAware->Aware执行点setMessageSource]
- [ApplicationContextAware->Aware执行点setApplicationContext]
- 执行初始化函数同时InitializingBean执行点
- [InitializingBean执行点afterPropertiesSet]
- 执行配置的init函数
把创建好的Bean放到singletonObjects
删除其他两个级别的缓存只存入到singletonObjects
待到全部Bean都创建好并放到执行InitializingBean,遍历Bean进行[SmartInitializingSingleton执行点afterSingletonsInstantiated]
分析
- mergedBD的作用就是合并BD,防止出现一个Bean名字多个对应关系却没有默认(@Primary)
$1=AbstractApplicationContext
#finishBeanFactoryInitialization()
for(String weaverAwareName : weaverAwareNames) {
//实例化实现了LoadTimeWeaverAware的类
#getBean(weaverAwareName);
}
// 实例化所有立即加载的单例bean
$1.beanFactory.preInstantiateSingletons();
$2=DefaultListableBeanFactory//$1.beanFactory
//获取Bean,若果是FB无限往里获取直到没有$
$2#getBean(beanName);
//AbstractBeanFactory真实获取Bean
$2#doGetBean();
//从singleobjects获取对应Bean
$2#getSingleton();
//回调Spring标志的SF
$3=$1&Lambda
$3#createBean();
//InstantiationAwareBeanPostProcessor执行点
$3#resolveBeforeInstantiation();
//创建Bean
$3#doCreateBean();
//获取BeanWrapped(实例化)
$3#createBeanInstance()
//MergedBeanDefinitionPostProcessor执行点
$3#applyMergedBeanDefinitionPostProcessors()
//把刚刚的Bean存入earlySingletonObjects
$3#addSingletonFactory(Lambda[getEarlyBeanReference()]);
//给Bean添加属性
$3#populateBean();
//InstantiationAwareBeanPostProcessor执行点
ibp.postProcessAfterInstantiation();
//InstantiationAwareBeanPostProcessor执行点
ibp.postProcessProperties();
//把Bean的属性存入BW(属性填充)
#applyPropertyValues();
$3#initializeBean();
//调用Aware相关执行点
$3#invokeAwareMethods();
//BeanPostProcessor执行点
$3#applyBeanPostProcessorsBeforeInitialization();
//执行初始化函数同时InitializingBean执行点
$3#invokeInitMethods()
//执行配置的init函数
$3#invokeCustomInitMethod()
//把创建好的Bean放到singletonObjects
$2#addSingleton();
//待到全部Bean都创建好并放到执行InitializingBean
for.smartSingleton.afterSingletonsInstantiated();
finishRefresh
完成context的刷新
调用LifecycleProcessor的onRefresh()方法
[Lifecycle执行点start]
发布事件(ContextRefreshedEvent)
$1=AbstractApplicationContext
#finishRefresh()
//调用LifecycleProcessor的onRefresh()方法,Lifecycle执行点
$1#getLifecycleProcessor().onRefresh()//调用LifecycleProcessor的回调
//发布事件(ContextRefreshedEvent)
$1#publishEvent(new ContextRefreshedEvent(this));//时间干了什么