Spring源码 - 容器刷新finishRefresh()

Spring源码 - 容器刷新finishRefresh()

Spring版本:Spring 5.3.13-release


Spring中提供了Lifecycle接口,Lifecycle接口中包含start()stop()以及isRunning()方法,实现此接口后Spring会保证在启动的时候调用其start()方法开始生命周期,并在Spring关闭的时候调用stop()方法来结束生命周期。通常用来配置后台程序,在启动后一直运行(如对MessageQueue进行轮询等操作)。Spring的容器刷新最后一步正是保证这一个功能的实现。

# 1、finishRefresh()完成容器刷新

AbstarctApplicationContext#finishRefresh()代码:

	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.
		// 刷新所有实现了 Lifecycle 接口的 Bean
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		// 发布 ContextRefreshEvent 事件告知容器已完成刷新
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		if (!NativeDetector.inNativeImage()) {
			LiveBeansView.registerApplicationContext(this);
		}
	}

# 2、initLifecycleProcessor()初始化LifecycleProcessor

ApplicationContext在启动或停止时, 它会通过LifecycleProcessor来与所有声明的Bean的周期做状态更新,这一步就是初始化LifecycleProcessor。需要注意的是,Spring会先从容器中获取BeanNamelifecycleProcessorBean实例,如果没有则使用Spring默认的DefaultLifecycleProcessor。所以开发者需要自定义LifecycleProcessor时一定需要将自己定义的LifecycleProcessor声明为lifecycleProcessor

ApplicationContext#initLifecycleProcessor()代码:

	protected void initLifecycleProcessor() {
		// 获取 BeanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		// 如果工厂中包存在 BeanName 为 lifecycleProcessor 的 Bean
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			// 获取该 Bean
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		else {
			// 工厂中不存在 BeanName 为 lifecycleProcessor 的 Bean
			// 使用 Spring 默认的 DefaultLifecycleProcessor
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			// 设置 BeanFactory
			defaultProcessor.setBeanFactory(beanFactory);
			// 赋值给当前容器中的 lifecycleProcessor
			this.lifecycleProcessor = defaultProcessor;
			// 以 BeanNam 为 lifecycleProcessor 注册到容器中
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
			}
		}
	}

# 3、getLifecycleProcessor().onRefresh()刷新所有实现了 Lifecycle 接口的 Bean

LifecycleProcessor初始化完成之后,调用LifecycleProcessor接口的onRefresh()方法刷新所有实现了LifecycleBean

DefaultLifecycleProcessor#startBeans()代码:

	private void startBeans(boolean autoStartupOnly) {
		// 获取所有实现了 Lifecycle 接口的 Bean
		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
		Map<Integer, LifecycleGroup> phases = new TreeMap<>();

		// 对需要进行启动的 Bean 进行筛选
		lifecycleBeans.forEach((beanName, bean) -> {
			if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
				int phase = getPhase(bean);
				phases.computeIfAbsent(
						phase,
						p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
				).add(beanName, bean);
			}
		});
		if (!phases.isEmpty()) {
			// 启动
			phases.values().forEach(LifecycleGroup::start);
		}
	}

# 3、publishEvent()发布容器刷新完成事件

当完成ApplicationContext容器刷新时,Spring通过事件发布机制发布ContextRefreshedEvent事件。以保证对应的监听器可以做进一步的逻辑处理。

AbstractApplicationContext#publishEvent()代码:

	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
		Assert.notNull(event, "Event must not be null");

		// Decorate event as an ApplicationEvent if necessary
		// 将事件封装为 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 {
			// 使用事件广播器, 广播事件
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}

		// Publish event via parent context as well...
		if (this.parent != null) {
			if (this.parent instanceof AbstractApplicationContext) {
				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
			}
			else {
				this.parent.publishEvent(event);
			}
		}
	}

至此Spring容器已完成刷新。

GitHub源码地址https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13

备注:此文为笔者学习Spring源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值