Spring 源码分析 01 -- refresh() 流程解析
本文主要描述了AbstractApplicationContext.refresh()的执行流程,通过流程图的方式进行展示,用以加深理解该过程.
- PS: 若文章字体偏大或者偏小,建议通过 ctrl键+鼠标滑轮 进行修改,以提升阅读效果.(带来不便,请谅解!)
Version:
jdk :1.8
Spring: 5.1.7
- PS: 注意Spring 版本, 不同版本的部分方法的实现可能存在差异.
- PS: 本系列以AnnotationConfigApplicationContext为例
refresh() 整体流程:
示图:
AbstractApplicationContext.java
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //1. Prepare this context for refreshing. prepareRefresh();// 校验配置文件,激活active, //2 Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//DefaultListableBeanFactory //3.对BeanFactory 进行预处理, 添加一些组件 environment, systemProperties,systemEnvironment //3.Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { //4. Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory);// 空方法 , 留给子类进行回调,对beanFactory进行增强 //5. 实例化 所有的BeanDefinitionRegistryPostPRocessor, BeanFactoryPostProcessor; //5. Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); //6. 实例化 并且注册 所有的BeanPostProcessor,按照 PriortyOrdered -> Ordered->regular -> internal -> ApplicationListenerDetector //6. Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // 7. 消息圆的初始化 // 7.Initialize message source for this context. initMessageSource();// 初始化消息源 有就赋值,无则创建 // 8. 初始化ApplicationEventMulticaster // 8. Initialize event multicaster for this context. initApplicationEventMulticaster();// 有就赋值,无则创建 // 9. 交给子类, 为子类回调 增强 // 9.Initialize other special beans in specific context subclasses. onRefresh(); // 10. 绑定事件监听器 与事件广播器,并且处理 earlyEvent // 10. Check for listener beans and register them. registerListeners(); // 11. 实例化所有的单例bean(不是懒加载的) // 11.Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // 12. // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
重要流程:
5-> 6-> 11
- 建议自己debug, 第一次试验时不要急于求成,不要想着一次性把所有的方法都看懂,不要每一步都压栈跟进去(不然就会迷失方向), 要做的是 保证大局观,保证自己知道当前每一个类所做的事,然后在下一次debug时进行深入理解.
- 总结: 看源码, 先总体,在局部.
1. prepareRefresh()
设置开始时间,以及 active (开始)标记, 占位符替换,以及数据校验
// 为节约用户阅读时间, 不重要的代码将采取主要逻辑的方式加以给出(伪代码)
// Switch to active.标记状态
// 替换 placeholder eg:${}
initPropertySources(); //
//数据校验
getEnvironment().validateRequiredProperties();// 校验数据, 并且保证 environment 已经加载
// 创建 early-listeners, early-event
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2. ObtainFreshBeanFactory()
- 创建BeanFactory,并返回.(DefaultListableBeanFactory.class)
refreshBeanFactory();//设置序列号
return getBeanFactory();// 获取beanFactory
AnnotationConfigApplicationContext 与ClassPathXmlApplicationContext 在这一步refreshBeanFactory() 会有不同
ps : 关于xml 的配置文件解析流程 推荐阅读 传送门
/**
AnnotationConfigApplicationContext:
GenericApplicationContext.refreshBeanFactory()
ClassPathXmlApplicationContext: xml 文件 -> bean definition
AbstractRefreshableApplicaitonContext.refreshBeanFactory()
**/
PS: 本系列以AnnotationConfigApplicationContext为例
3. prepareBeanFactory(BeanFactory) ;
对BeanFactory 进行预处理, 添加一些组件 environment, systemProperties,systemEnvironment
无趣的代码, 只是设置了一些属性, 注入了一些基本组件到BeanFactory
如果想要了解细节 推荐阅读传送门(多嘴一句, javadoop 的作者写的是bean的创创建流程 本文改不探讨, 会放在下一篇文章中进行输出)
4. postProcessBeanFactory(beanFactory);
// 空方法 , 留给子类进行回调,对beanFactory进行增强
5. invokeBeanFactoryPostProcessors(beanFactory);
//5. 实例化 所有的BeanFactoryPostProcessor,
// 按照BeanDefinitionRegistryPostPRocessor, BeanFactoryPostProcessor顺序处理
// PriorityOrdered -> Ordered -> 余下的BeanFactoryPostProcessor 顺序进行初始化
// 如下图所示
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
//委托给PostProcessorRegistrationDelegate 去创建BeanFactoryPostProcessor,
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // 处理Weave 即AOP
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
生成BeanFactoryPostProcessor 过程.
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
示图:
人话描述执行流程 :
BeanDefinitionRegistryPostProcessor :
- 分类 , 用一个 List
list 进行保存 - 排序
- invoke : 按照 PriorityOrdered -> Ordered -> the rest 顺序生成
- 分类 , 用一个 List
BeanFactoryPostProcessor:
- 分类
- 排序
- invoke : 按照 PriorityOrdered -> Ordered -> the rest 顺序生成
题外话:
已知 BeanDefinitionRegistryPostProcessor 继承 BeanFactoryPostProcessor接口,并且两者都按照 PriorityOrdered -> Ordered -> the rest 进行实例化, 那是不是可以抽一个方法来代替这个过程,使程序代码更加简洁?
代码实现:
// 1.Invoke BeanDefinitionRegistryPostProcessors, BeanFactoryPostProcessor
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 1. 分类 ,并注册 BeanDefinitionRegistryPostProcessor
// 1. Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
//1.1 将 BeanFactoryPostProcessor 分类 -> BeanFactoryPostProcessor ,BeanDefinitionRegistryPostProcessor
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// 1.2 PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 1.2.1 注册BeanDefinitionRegistryPostProcessor 实现 PriorityOrdered 接口的进行注册(实例化)
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);// 排序 BeanDefinitionRegistryPostProcessor
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 实例化
currentRegistryProcessors.clear();
// 1.2.2 Ordered
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 1.2.3 余下的
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//2 . 实例化BeanFactoryPostProcessor, 按照 riorityOrdered, Ordered, and the rest.
//2. Do not initialize FactoryBeans here: We need to leave all regular beans, // 不要在这里初始化factorybean(在所有bean未初始化之前,使得bean factory postprocessor 可以用)
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames = // 获取BeanFactoryPostProcessor
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 2.1 分类, PriorityOrdered-> Ordered -> the rest
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 2.2 实例化 PriorityOrdered
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 2.3 实例化 Ordered
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
//2.4 实例化 the rest
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
6. registerBeanPostProcessors(beanFactory);
说明: 步骤 5 invokeBeanFactoryPostProcessor(BeanFactory) 与 步骤6 registerBeanPostProcessor(BeanFactory) 方法大致相同, 因而不会贴出此代码
//6. 实例化 并且注册 所有的BeanPostProcessor,按照 PriortyOrdered -> Ordered->regular -> internal -> ApplicationListenerDetector
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}
7. initMessageSource();
消息源的初始化.
8. initApplicationEventMulticaster();
初始化ApplicationEventMulticaster,有就直接用没有就创建的原则
9. onRefresh();
交给子类决定,方法增强
10. registerListeners();
// 10. 绑定事件监听器 与事件广播器,并且处理 earlyEvent
protected void registerListeners() {
// Register statically specified listeners first. 将消息多播器与监听器绑定
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 发布 early application event
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
11. finishBeanFactoryInitialization(beanFactory);
实例化所有的单例bean(不是懒加载的@lazy)
主要的方法: beanFactory.preInstantiateSingletons();
流程图:
- 创建bean的过程不会在这里说明,会单独写一篇文章来说明的.
// 实例化所有的单例 bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.// 转换 thread-safe
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 注册字符串解析器
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 处理 AspectJ AOP类
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// 加锁, 避免配置类信息发生 改变 volatile
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// 实例化所有的单例bean(不包含懒加载)
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
12. finishRefresh();
清缓存,发布容器刷新完成事件
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches(); //清缓存
// Initialize lifecycle processor for this context.
initLifecycleProcessor();// 注册 lifecycleProcessor
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));//发布容器刷新完成事件
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
总结:
关于Spring容器中的组件, bean, 等都是按照”先去拿,没有在创建“的原则 进行初始化,这一点, 在 步骤11 finishBeanFactoryInitialization(beanFactory) 中尤为明显.
- eg : messageSource, ApplicationEventMulticaster
需要关注的类:
- AbstractApplicationContext.java
- PostProcessorRegistrationDelegate.java
参考:
- https://javadoop.com/post/spring-ioc
- https://docs.spring.io/spring-framework/docs/5.1.7.RELEASE/spring-framework-reference/core.html#spring-core
- https://www.bilibili.com/video/BV1gW411W7wy