Spring源码之九finishRefresh详解

博客 分享
0 240
张三
张三 2022-03-11 17:56:27
悬赏:0 积分 收藏

Spring源码之九finishRefresh详解

Spring IoC 的核心内容要收尾了,本文将对最后一个方法 finishRefresh 进行介绍,位于refresh 方法中的第九个位置。本章实际是对发布订阅模式的一种补充,这是Spring在刷新事件完成后发布事件。

Spring源码之九finishRefresh详解

公众号搜索【程序员田同学】,专职程序员兼业余写手,生活不止于写代码

Spring IoC 的核心内容要收尾了,本文将对最后一个方法 finishRefresh 进行介绍,位于refresh 方法中的第九个位置。

本章实际是对发布订阅模式的一种补充,这是Spring在刷新事件完成后发布事件。

由于存在上下文关系,本文也会对 initApplicationEventMulticaster 方法、registerListeners 方法进行回顾。

我们回到refresh 方法中。

@Override	public void refresh() throws BeansException, IllegalStateException {		synchronized (this.startupShutdownMonitor) {			// Prepare this context for refreshing.			//1、刷新前的准备			prepareRefresh();			// Tell the subclass to refresh the internal bean factory.			//2、将会初始化 BeanFactory、加载 Bean、注册 Bean			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();			// Prepare the bean factory for use in this context.			//3、设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean			prepareBeanFactory(beanFactory);			try {				//4、模板方法				// Allows post-processing of the bean factory in context subclasses.				postProcessBeanFactory(beanFactory);				// Invoke factory processors registered as beans in the context.				//执行BeanFactory后置处理器				invokeBeanFactoryPostProcessors(beanFactory);				// 5、Register bean processors that intercept bean creation.				//注册bean后置处理器				registerBeanPostProcessors(beanFactory);				// Initialize message source for this context.				//国际化				initMessageSource();				// Initialize event multicaster for this context.				//初始化事件广播器				initApplicationEventMulticaster();				// Initialize other special beans in specific context subclasses.				//6、模板方法--springboot实现了这个方法				onRefresh();				// Check for listener beans and register them.				//7、注册监听器				registerListeners();				// Instantiate all remaining (non-lazy-init) singletons.				//8、完成bean工厂的初始化**方法重要**********************************************				finishBeanFactoryInitialization(beanFactory);				//9、 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();			}		}	}

我们首先知道这个三个方法的作用:

initApplicationEventMulticaster():初始化应用的事件广播器

/**	 * Initialize the ApplicationEventMulticaster.	 * Uses SimpleApplicationEventMulticaster if none defined in the context.	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster	 */	protected void initApplicationEventMulticaster() {		ConfigurableListableBeanFactory beanFactory = getBeanFactory();		// 1.判断BeanFactory是否已经存在事件广播器(固定使用beanName=applicationEventMulticaster)		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {			// 1.1 如果已经存在,则将该bean赋值给applicationEventMulticaster			this.applicationEventMulticaster =					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);			if (logger.isTraceEnabled()) {				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");			}		}		else {			// 1.2 如果不存在,则使用SimpleApplicationEventMulticaster			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() + "]");			}		}	}

最终只做了一件事,初始化应用的事件广播器。(具体什么是事件广播器及其作用可见上上篇文章,具体就不在吃赘述了)

registerListeners():注册监听器。见上上篇文章

finishRefresh():完成上下文的刷新工作,本文重点

首先概览finishRefresh方法

	protected void finishRefresh() {		// Clear context-level resource caches (such as ASM metadata from scanning).		//清除资源缓存		clearResourceCaches();		// Initialize lifecycle processor for this context.		// // 1.为此上下文初始化生命周期处理器		initLifecycleProcessor();		// Propagate refresh to lifecycle processor first.		// 2.首先将刷新完毕事件传播到生命周期处理器(触发isAutoStartup方法返回true的SmartLifecycle的start方法)		getLifecycleProcessor().onRefresh();		// Publish the final event.		// 3.推送上下文刷新完毕事件到相应的监听器		publishEvent(new ContextRefreshedEvent(this));		// Participate in LiveBeansView MBean, if active.		LiveBeansView.registerApplicationContext(this);	}

1、2、3是重点内容

1.为此上下文初始化生命周期处理器

	protected void initLifecycleProcessor() {		ConfigurableListableBeanFactory beanFactory = getBeanFactory();		// 1.判断BeanFactory是否已经存在生命周期处理器(固定使用beanName=lifecycleProcessor)		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {			this.lifecycleProcessor =					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);			if (logger.isTraceEnabled()) {				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");			}		}		else {			// 1.2 如果不存在,则使用DefaultLifecycleProcessor			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();			defaultProcessor.setBeanFactory(beanFactory);			this.lifecycleProcessor = defaultProcessor;			// 并将DefaultLifecycleProcessor作为默认的生命周期处理器,注册到BeanFactory中			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);			if (logger.isTraceEnabled()) {				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");			}		}	}

2.首先将刷新完毕事件传播到生命周期处理器

private void startBeans(boolean autoStartupOnly) {		// 1.获取所有的Lifecycle bean		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();		// 将Lifecycle bean 按阶段分组,阶段通过实现Phased接口得到		Map<Integer, LifecycleGroup> phases = new HashMap<>();		// 2.遍历所有Lifecycle bean,按阶段值分组		lifecycleBeans.forEach((beanName, bean) -> {			// autoStartupOnly=true代表是ApplicationContext刷新时容器自动启动;autoStartupOnly=false代表是通过显示的调用启动			// 3.当autoStartupOnly=false,也就是通过显示的调用启动,会触发全部的Lifecycle;			// 当autoStartupOnly=true,也就是ApplicationContext刷新时容器自动启动,只会触发isAutoStartup方法返回true的SmartLifecycle			if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {				// 3.1 获取bean的阶段值(如果没有实现Phased接口,则值为0)				int phase = getPhase(bean);				// 3.2 拿到存放该阶段值的LifecycleGroup			   LifecycleGroup group = phases.get(phase);				if (group == null) {					// 3.3 如果该阶段值的LifecycleGroup为null,则新建一个					group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);					phases.put(phase, group);				}				// 3.4 将bean添加到该LifecycleGroup				group.add(beanName, bean);			}		});		// 4.如果phases不为空		if (!phases.isEmpty()) {			List<Integer> keys = new ArrayList<>(phases.keySet());			// 4.1 按阶段值进行排序			Collections.sort(keys);			// 4.2 按阶段值顺序,调用LifecycleGroup中的所有Lifecycle的start方法			for (Integer key : keys) {				phases.get(key).start();			}		}	}

3.推送上下文刷新完毕事件到相应的监听器

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {		Assert.notNull(event, "Event must not be null");		// Decorate event as an ApplicationEvent if necessary		// 1.如有必要,将事件装饰为ApplicationEvent		ApplicationEvent applicationEvent;		if (event instanceof ApplicationEvent) {			applicationEvent = (ApplicationEvent) event;		}		else {			applicationEvent = new PayloadApplicationEvent<>(this, event);			if (eventType == null) {				eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();			}		}		// Multicast right now if possible - or lazily once the multicaster is initialized		if (this.earlyApplicationEvents != null) {			this.earlyApplicationEvents.add(applicationEvent);		}		else {			// 2.使用事件广播器广播事件到相应的监听器			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);		}		// Publish event via parent context as well...		// 3.同样的,通过parent发布事件.....		if (this.parent != null) {			if (this.parent instanceof AbstractApplicationContext) {				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);			}			else {				this.parent.publishEvent(event);			}		}	}

这里面调用的publishEvent方法,和我们自定义的监听器调用的publishEvent是同一个方法,ContextRefreshedEvent是Spirng的一个事件称为上下文刷新完毕事件,如果我们在上下文刷新完成后要写一个发布事件,实现ApplicationListener接口即可。

我们在此举一个简单的例子。

image-20220311162737098

image-20220311162803318

这样,当 Spring 执行到 finishRefresh 方法时,就会将 ContextRefreshedEvent 事件推送到 MyRefreshedListener 中。

读者可以结合自定义事件对比一个和Spring提供的刷新上下文事件的区别,以便于更好的理解Spring的事件监听机制。

跟 ContextRefreshedEvent 相似的还有:ContextStartedEvent、ContextClosedEvent、ContextStoppedEvent。

好啦,Spirng的refresh方法到这里就结束啦,一共是九篇博客,实际上这也是Spirng的IOC的全部内容了,如果读者能把九篇的完全消化,那么spring的IOC也就理解的七七八八了。

posted @ 2022-03-11 17:00 程序员田同学 阅读(22) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员