前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring5 源码学习 (8) refresh方法总结

Spring5 源码学习 (8) refresh方法总结

作者头像
Coder小黑
发布2019-12-18 14:50:57
4910
发布2019-12-18 14:50:57
举报
文章被收录于专栏:Coder小黑Coder小黑

废话不多说,直接上源码注释:

代码语言:javascript
复制
//AbstractApplicationContext#refresh源码
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		//准备上下文,设置其启动日期和活动标志,执行属性源的初始化
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		//调用子类 refreshBeanFactory()方法
		//获取 BeanFactory 实例 DefaultListableBeanFactory , DefaultListableBeanFactory 实现了 ConfigurableListableBeanFactory 接口
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		//配置 beanFactory 上下文
		//1.添加 ApplicationContextAwareProcessor 和 ApplicationListenerDetector
		//2.忽略部分类型的自动装配
		//3.注册特殊的依赖类型,并使用相应的autowired值
		//4.注册默认的environment beans
		//5.设置environment beans
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			//留给子类去扩展的一个方法
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			//执行BeanFactoryPostProcessors
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			// 注册BeanPostProcessors
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			// 初始化信息源,作国际化相关
			initMessageSource();

			// Initialize event multicaster for this context.
			// 初始化容器实现传播器,也就是往容器中添加了一个Bean
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			// 在特定 ApplicationContext 的子类中触发某些特殊的Bean初始化
			// 在此处AbstractApplicationContext.onRefresh 是一个空方法
			onRefresh();

			// Check for listener beans and register them.
			// 注册 ApplicationListener
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			// 初始化所有还未被初始化的单例bean
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			// 容器启动完成,清理缓存, 发布 ContextRefreshedEvent 事件
			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.
			// 销毁已创建的单例bean
			destroyBeans();

			// Reset 'active' flag.
			// 取消Refresh,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();
		}
	}
}

之前已经分析到了invokeBeanFactoryPostProcessors方法,现在来看一下registerBeanPostProcessors

registerBeanPostProcessors

registerBeanPostProcessors,顾名思义主要在注册BeanPostProcessor,该方法的具体逻辑委托给了PostProcessorRegistrationDelegate#registerBeanPostProcessors方法,我们直接来看该方法源码:

代码语言:javascript
复制
public static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

	//从 beanDefinitionNames 中获取类型为 BeanPostProcessor 的 beanName
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// Register BeanPostProcessorChecker that logs an info message when
	// a bean is created during BeanPostProcessor instantiation, i.e. when
	// a bean is not eligible for getting processed by all BeanPostProcessors.
	// BeanPostProcessorChecker 实现了 BeanPostProcessor接口
	// 用来判断当前 bean 是否已经执行了所有的 BeanPostProcessor
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// Separate between BeanPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	// 对 BeanPostProcessor 进行分类排序
	// 实现 PriorityOrdered 接口的 BeanPostProcessor
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	// 实现 MergedBeanDefinitionPostProcessor 接口的 BeanPostProcessor
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	// 实现 Ordered 接口的 BeanPostProcessor 的 BeanName
	List<String> orderedPostProcessorNames = new ArrayList<>();
	// 普通的 BeanPostProcessor 的 BeanName
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		} else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// First, register the BeanPostProcessors that implement PriorityOrdered.
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);

	// 注册实现 PriorityOrdered 接口的 BeanPostProcessor
	// 底层循环List调用 beanFactory.addBeanPostProcessor(postProcessor); 方法
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// Next, register the BeanPostProcessors that implement Ordered.
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);

	// 注册实现 Ordered 接口的 BeanPostProcessor
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// Now, register all regular BeanPostProcessors.
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}

	//注册普通的 BeanPostProcessor
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// Finally, re-register all internal BeanPostProcessors.
	sortPostProcessors(internalPostProcessors, beanFactory);
	//注册实现 MergedBeanDefinitionPostProcessor 接口的 BeanPostProcessor
	registerBeanPostProcessors(beanFactory, internalPostProcessors);

	// Re-register post-processor for detecting inner beans as ApplicationListeners,
	// moving it to the end of the processor chain (for picking up proxies etc).
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

是不是有种似曾相识的感受,嗯...这个源码的内部套路和invokeBeanFactoryPostProcessors方法差不多。

  1. 从beanDefinitionNames中获取类型为BeanPostProcessor的所有beanName
  2. 遍历所有的postProcessorNames,将其分类:
    • 实现PriorityOrdered接口的
    • 实现MergedBeanDefinitionPostProcessor接口的
    • 实现Ordered接的
    • 普通的BeanPostProcessor
  3. 按一定是先后顺序依次执行所有的为BeanPostProcessor,具体可查看上述源码。

initMessageSource

initMessageSource方法负责,初始化信息源,是一些国际化相关功能,我们忽略。

initApplicationEventMulticaster

初始化容器实现传播器,也就是往容器中添加了一个Bean,具体代码如下:

代码语言:javascript
复制
protected void initApplicationEventMulticaster() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		this.applicationEventMulticaster =
				beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
		if (logger.isTraceEnabled()) {
			logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
		}
	} else {
		this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
		beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
		if (logger.isTraceEnabled()) {
			logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
					"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
		}
	}
}

onRefresh

onRefresh方法在此处AbstractApplicationContext.onRefresh是一个空方法,其作用是在特定ApplicationContext的子类中触发某些特殊的Bean初始化。

registerListeners

注册ApplicationListener,源码如下:

代码语言:javascript
复制
protected void registerListeners() {
	// Register statically specified listeners first.
	// 这里的 applicationListeners 是需要我们手动调用 AbstractApplicationContext.addApplicationListener 方法才会有内容
	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);
	}

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

finishBeanFactoryInitialization(beanFactory);

初始化所有还未被初始化的单例bean。AbstractApplicationContext#finishBeanFactoryInitialization调用DefaultListableBeanFactory#preInstantiateSingletons

代码语言:javascript
复制
//DefaultListableBeanFactory#preInstantiateSingletons源码:
public void preInstantiateSingletons() throws BeansException {
	if (logger.isTraceEnabled()) {
		logger.trace("Pre-instantiating singletons in " + this);
	}

	// Iterate over a copy to allow for init methods which in turn register new bean definitions.
	// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
	// 获取所有的beanDefinitionNames
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

	// Trigger initialization of all non-lazy singleton beans...
	// 遍历所有的beanDefinitionNames
	for (String beanName : beanNames) {
		// 根据指定的beanName获取其父类的相关公共属性,返回合并的RootBeanDefinition
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 如果不是抽象类,而且是单例,又不是懒加载
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 判断是不是FactoryBean
			if (isFactoryBean(beanName)) {
				// 如果是FactoryBean,使用 &+beanName ,去获取 FactoryBean
				// 为什么要这样做,因为beanName获取的是FactoryBean生产的Bean,要获取FactoryBean本身,需要通过&+beanName
				// 其实,实例化所有的非懒加载单例Bean的时候,如果是FactoryBean,这里只是创建了FactoryBean
				// 什么时候去创建由FactoryBean产生的Bean呢? 好像也是懒加载的,在使用到这个Bean的时候,才通过FactoryBean去创建Bean
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				if (bean instanceof FactoryBean) {
					final FactoryBean<?> factory = (FactoryBean<?>) bean;
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
										((SmartFactoryBean<?>) factory)::isEagerInit,
								getAccessControlContext());
					} else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
			} else {
				// 不是FactoryBean
				getBean(beanName);
			}
		}
	}

	// Trigger post-initialization callback for all applicable beans...
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		// Spring容器的一个拓展点SmartInitializingSingleton
		// 在所有非懒加载单例Bean创建完成之后调用该接口 @since 4.1
		if (singletonInstance instanceof SmartInitializingSingleton) {
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			} else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}
  1. 获取所有的beanDefinitionNames,然后遍历
  2. 先合并其父类的相关公共属性,返回合并的RootBeanDefinition
  3. 如果不是抽象类,而且是非懒加载的单例则开始创建Bean
  4. 首先判断是不是FactoryBean,如果是FactoryBean,使用 &+beanName ,去获取 FactoryBean
  5. 如果不是FactoryBean,则直接调用getBean(beanName);方法创建或者获取对应的Bean
  6. SmartInitializingSingletonSpring4.1版本之后的一个新扩展点。在创建完所有的非懒加载单例Bean之后,调用SmartInitializingSingleton接口,完成回调。

finishRefresh

容器启动完成,清理缓存,发布ContextRefreshedEvent事件。

代码语言:javascript
复制
protected void finishRefresh() {
	// Clear context-level resource caches (such as ASM metadata from scanning).
	clearResourceCaches();

	// Initialize lifecycle processor for this context.
	initLifecycleProcessor();

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

源码注释GITHUB地址:https://github.com/shenjianeng/spring-code-study

未完待续......

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder小黑 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • registerBeanPostProcessors
  • initMessageSource
  • initApplicationEventMulticaster
  • onRefresh
  • registerListeners
  • finishBeanFactoryInitialization(beanFactory);
  • finishRefresh
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档