Spring 源码分析 01 -- refresh() 流程解析

本文主要描述了AbstractApplicationContext.refresh()的执行流程,通过流程图的方式进行展示,用以加深理解该过程.

image-20210308165700429

  • PS: 若文章字体偏大或者偏小,建议通过 ctrl键+鼠标滑轮 进行修改,以提升阅读效果.(带来不便,请谅解!)

Version:

jdk :1.8
Spring: 5.1.7 
  • PS: 注意Spring 版本, 不同版本的部分方法的实现可能存在差异.
  • PS: 本系列以AnnotationConfigApplicationContext为例

refresh() 整体流程:

示图: 1615177530243

  • 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()

1615178870105

设置开始时间,以及 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
  • AnnotationConfigApplicationContextClassPathXmlApplicationContext 在这一步refreshBeanFactory() 会有不同

    ps : 关于xml 的配置文件解析流程 推荐阅读 传送门

/**
AnnotationConfigApplicationContext: 
	GenericApplicationContext.refreshBeanFactory()
	
ClassPathXmlApplicationContext: xml 文件 -> bean definition
	AbstractRefreshableApplicaitonContext.refreshBeanFactory()
**/
  • PS: 本系列以AnnotationConfigApplicationContext为例


3. prepareBeanFactory(BeanFactory) ;

1615178949906

  • 对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());

  • 示图:

  • 人话描述执行流程 :

    1. BeanDefinitionRegistryPostProcessor :

      1. 分类 , 用一个 List list 进行保存
      2. 排序
      3. invoke : 按照 PriorityOrdered -> Ordered -> the rest 顺序生成
    2. BeanFactoryPostProcessor:

      1. 分类
      2. 排序
      3. 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) 方法大致相同, 因而不会贴出此代码

1615178990805

//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();

  • 流程图:1615181273524

  • 创建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