Spring IoC源码学习:finishRefresh 详解

本文详细解读了一线大厂Java面试中可能涉及的问题,重点关注Spring框架中的ApplicationContext初始化过程,包括BeanFactory的配置、BeanPostProcessors的注册、LifecycleProcessor的初始化以及ApplicationEventMulticaster的管理。提供学习笔记和实战项目源码链接供深入学习。
摘要由CSDN通过智能技术生成

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

prepareRefresh();

// Tell the subclass to refresh the internal bean factory.

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.

prepareBeanFactory(beanFactory);

try {

// Allows post-processing of the bean factory in context subclasses.

postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.

invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.

registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.

initMessageSource();

// Initialize event multicaster for this context.

initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.

onRefresh();

// Check for listener beans and register them.

registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.

finishBeanFactoryInitialization(beanFactory);

// 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():初始化应用的事件广播器,见代码块1详解

registerListeners():注册监听器,见代码块2详解

finishRefresh():完成上下文的刷新工作,见代码块3详解

代码块1:initApplicationEventMulticaster


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.isDebugEnabled()) {

logger.debug(“Using ApplicationEventMulticaster [” + this.applicationEventMulticaster + “]”);

}

} else {

// 1.2 如果不存在,则使用SimpleApplicationEventMulticaster

this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);

// 并将SimpleApplicationEventMulticaster作为默认的事件广播器,注册到BeanFactory中

beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);

if (logger.isDebugEnabled()) {

logger.debug(“Unable to locate ApplicationEventMulticaster with name '” +

APPLICATION_EVENT_MULTICASTER_BEAN_NAME +

“': using default [” + this.applicationEventMulticaster + “]”);

}

}

}

内容比较简单,就是要初始化应用的事件广播器。通过之前的学习我们知道,在 Spring 中,有一些内部的 bean 会使用固定的 beanName,这边的事件广播器就是这样,固定使用 beanName :applicationEventMulticaster。

具体的,如果当前 BeanFactory 中已经存在 beanName = applicationEventMulticaster 的 bean 实例或者 BeanDefinition,那么就使用该 bean 作为 applicationEventMulticaster。

否则,新建一个默认的事件广播器 SimpleApplicationEventMulticaster 作为 applicationEventMulticaster,并且会注册到 BeanFactory 中。

代码块2:registerListeners


protected void registerListeners() {

// Register statically specified listeners first.

// 1.通过硬编码调用addApplicationListener方法添加的监听器处理(可以通过自定义ApplicationContextInitializer添加)

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!

// 2.通过配置文件或注解注入BeanFactory的监听器处理

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…

// 3.使用事件广播器,发布早期应用程序事件到相应的监听器

Set earlyEventsToProcess = this.earlyApplicationEvents;

this.earlyApplicationEvents = null;

if (earlyEventsToProcess != null) {

for (ApplicationEvent earlyEvent : earlyEventsToProcess) {

getApplicationEventMulticaster().multicastEvent(earlyEvent);

}

}

}

1.通过硬编码调用 addApplicationListener 方法添加的监听器处理,可以通过自定义 ApplicationContextInitializer 添加,关于自定义 ApplicationContextInitializer 请见 Spring IoC:ApplicationContext 刷新前的配置 中的代码块12

代码块3:finishRefresh


protected void finishRefresh() {

// 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.为此上下文初始化生命周期处理器,见代码块4详解

2.首先将刷新完毕事件传播到生命周期处理器,见代码块5详解

3.推送上下文刷新完毕事件到相应的监听器,见代码块6详解

代码块4:initLifecycleProcessor


protected void initLifecycleProcessor() {

ConfigurableListableBeanFactory beanFactory = getBeanFactory();

// 1.判断BeanFactory是否已经存在生命周期处理器(固定使用beanName=lifecycleProcessor)

if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {

// 1.1 如果已经存在,则将该bean赋值给lifecycleProcessor

this.lifecycleProcessor =

beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);

if (logger.isDebugEnabled()) {

logger.debug(“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.isDebugEnabled()) {

logger.debug(“Unable to locate LifecycleProcessor with name '” +

LIFECYCLE_PROCESSOR_BEAN_NAME +

“': using default [” + this.lifecycleProcessor + “]”);

}

}

}

初始化生命周期处理器,过程同代码块1类似,优先使用用户自定义的生命周期处理器;如果用户没有自定义,则使用默认的 DefaultLifecycleProcessor。

代码块5:onRefresh


@Override

public void onRefresh() {

startBeans(true);

this.running = true;

}

private void startBeans(boolean autoStartupOnly) {

// 1.获取所有的Lifecycle bean

Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();

// 将Lifecycle bean 按阶段分组,阶段通过实现Phased接口得到

Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();

// 2.遍历所有Lifecycle bean,按阶段值分组

for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {

Lifecycle bean = entry.getValue();

// 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(entry.getKey(), bean);

}

}

// 4.如果phases不为空

if (!phases.isEmpty()) {

List keys = new ArrayList(phases.keySet());

// 4.1 按阶段值进行排序

Collections.sort(keys);

// 4.2 按阶段值顺序,调用LifecycleGroup中的所有Lifecycle的start方法

for (Integer key : keys) {

phases.get(key).start();

}

}

}

这边讲下 autoStartupOnly 这个参数。

autoStartupOnly = true 时,代表这次刷新是 ApplicationContext 刷新时容器自动启动,在这个阶段只会触发 SmartLifecycle,并且要求 SmartLifecycle 的 isAutoStartup() 方法必须返回 true。

而 autoStartupOnly = false,代表这次刷新是通过显示的调用启动,会触发所有的 Lifecycle。

这边还引入了 Phased 接口,这个接口类似于 Ordered 接口,只有一个方法用于返回一个 “阶段值”,范围为 Integer.MIN_VALUE ~ Integer.MAX_VALUE。在启动过程,“阶段值” 小的会被优先调用,而在关闭过程,“阶段值” 大的会被优先调用。

代码块6:publishEvent


@Override

public void publishEvent(ApplicationEvent event) {

publishEvent(event, null);

}

protected void publishEvent(Object event, ResolvableType eventType) {

Assert.notNull(event, “Event must not be null”);

if (logger.isTraceEnabled()) {

logger.trace("Publishing event in " + getDisplayName() + ": " + event);

}

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

}

}

}

2.使用事件广播器广播事件到相应的监听器,见代码块7详解

代码块7:multicastEvent


@Override

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {

ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));

// 1.getApplicationListeners:返回与给定事件类型匹配的应用监听器集合

for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {

// 2.返回此广播器的当前任务执行程序

Executor executor = getTaskExecutor();

if (executor != null) {

executor.execute(new Runnable() {

@Override

public void run() {

// 3.1 executor不为null,则使用executor调用监听器

invokeListener(listener, event);

}

});

} else {

// 3.2 否则,直接调用监听器

invokeListener(listener, event);

}

}

}

3.2 调用监听器,见代码块8详解

代码块8:invokeListener


架构学习资料

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
// 3.1 executor不为null,则使用executor调用监听器

invokeListener(listener, event);

}

});

} else {

// 3.2 否则,直接调用监听器

invokeListener(listener, event);

}

}

}

3.2 调用监听器,见代码块8详解

代码块8:invokeListener


架构学习资料

[外链图片转存中…(img-vuEv3vbF-1714751570790)]

[外链图片转存中…(img-IJvchty7-1714751570790)]

[外链图片转存中…(img-qUIZXQdY-1714751570790)]

[外链图片转存中…(img-lEP4VvFW-1714751570791)]

[外链图片转存中…(img-vmIiiV84-1714751570791)]

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 11
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值