目录
Spring IoC源码学习全系列
前言
正文
代码块1:initApplicationEventMulticaster
代码块2:registerListeners
代码块3:finishRefresh
代码块4:initLifecycleProcessor
代码块5:onRefresh
代码块6:publishEvent
代码块7:multicastEvent
代码块8:invokeListener
自定义监听器实现
总结
相关文章
小白也看得懂的 Spring IoC 核心流程介绍
Spring IoC源码学习:总览
Spring IoC源码学习:ApplicationContext 刷新前的配置
Spring IoC源码学习:obtainFreshBeanFactory详解
Spring IoC源码学习:parseDefaultElement详解
Spring IoC源码学习:parseCustomElement详解
Spring IoC源码学习:obtainFreshBeanFactory详解
Spring IoC源码学习:invokeBeanFactoryPostProcessors详解
Spring IoC源码学习:registerBeanPostProcessors详解
Spring IoC源码学习:finishBeanFactoryInitialization详解
Spring IoC源码学习:getBean详解
Spring IoC源码学习:createBean详解(上)
Spring IoC源码学习:createBean详解(下)
Spring IoC源码学习:@Autowire 详解
Spring IoC源码学习:finishRefresh 详解
Spring IoC 的核心内容已经介绍完毕,本文将对最后一个方法 finishRefresh 进行介绍。由于存在上下文关系,本文也会对 initApplicationEventMulticaster 方法、registerListeners 方法进行介绍。
首先,我们回到 refresh 方法。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
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详解。
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 中。
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。
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详解。
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。
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
private void startBeans(boolean autoStartupOnly) {
// 1.获取所有的Lifecycle bean
Map lifecycleBeans = getLifecycleBeans();
// 将Lifecycle bean 按阶段分组,阶段通过实现Phased接口得到
Map phases = new HashMap();
// 2.遍历所有Lifecycle bean,按阶段值分组
for (Map.Entry 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。在启动过程,“阶段值” 小的会被优先调用,而在关闭过程,“阶段值” 大的会被优先调用。
@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
2.使用事件广播器广播事件到相应的监听器,见代码块7详解。
@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详解。
protected void invokeListener(ApplicationListener> listener, ApplicationEvent event) {
// 1.返回此广播器的当前错误处理程序
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
// 2.1 如果errorHandler不为null,则使用带错误处理的方式调用给定的监听器
doInvokeListener(listener, event);
} catch (Throwable err) {
errorHandler.handleError(err);
}
} else {
// 2.2 否则,直接调用调用给定的监听器
doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
// 触发监听器的onApplicationEvent方法,参数为给定的事件
listener.onApplicationEvent(event);
} catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || msg.startsWith(event.getClass().getName())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
Log logger = LogFactory.getLog(getClass());
if (logger.isDebugEnabled()) {
logger.debug("Non-matching event type for listener: " + listener, ex);
}
} else {
throw ex;
}
}
}
如果我们想在 Spring IoC 容器构建完毕之后进行一些逻辑,就可以通过监听器来实现。
创建一个自定义监听器,实现 ApplicationListener 接口,监听 ContextRefreshedEvent(上下文刷新完毕事件),并且将该监听器注册到 Spring IoC 容器即可。
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
/**
* @author joonwhee
* @date 2019/6/22
*/
@Component
public class MyRefreshedListener implements ApplicationListener {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 自己的逻辑处理
}
}
这样,当 Spring 执行到 finishRefresh 方法时,就会将 ContextRefreshedEvent 事件推送到 MyRefreshedListener 中。
跟 ContextRefreshedEvent 相似的还有:ContextStartedEvent、ContextClosedEvent、ContextStoppedEvent,有兴趣的可以自己看看这几个事件的使用场景。
当然,我们也可以自定义监听事件,只需要继承 ApplicationContextEvent 抽象类即可。
本文主要介绍了几个用于扩展使用的功能: