抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

SpringIOC-完成刷新工作

前言

​ Spring IoC 的核心内容已经介绍完毕,本文将对最后一个方法 finishRefresh 进行介绍。由于存在上下文关系,本文也会对 initApplicationEventMulticaster 方法、registerListeners 方法进行介绍。

refresh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
* 该方法是spring容器初始化的核心方法。是spring容器初始化的核心流程,是一个典型的父类模板设计模式的运用
* 根据不同的上下文对象,会掉到不同的上下文对象子类方法中
*
* 核心上下文子类有:
* ClassPathXmlApplicationContext
* FileSystemXmlApplicationContext
* AnnotationConfigApplicationContext
* EmbeddedWebApplicationContext(springboot)
*
* 方法重要程度:
* 0:不重要,可以不看
* 1:一般重要,可看可不看
* 5:非常重要,一定要看
*
*
* 必须读的 :重要程度 5
* */
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//为容器初始化做准备,重要程度:0
// Prepare this context for refreshing.
prepareRefresh();

/**
*重要程度:5
* 1、创建BeanFactory对象
* 2、xml解析
* 传统标签解析:bean、import等
* 自定义标签解析 如:<context:component-scan base-package="com.xiangxue.jack"/>
* 自定义标签解析流程:
* a、根据当前解析标签的头信息找到对应的namespaceUri
* b、加载spring所以jar中的spring.handlers文件。并建立映射关系
* c、根据namespaceUri从映射关系中找到对应的实现了NamespaceHandler接口的类
* d、调用类的init方法,init方法是注册了各种自定义标签的解析类
* e、根据namespaceUri找到对应的解析类,然后调用paser方法完成标签解析
*
* 3、把解析出来的xml标签封装成BeanDefinition对象
* */
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

//给beanFactory设置一些属性值,可以不看
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);

/**
* BeanDefinitionRegistryPostProcessor
* BeanFactoryPostProcessor
* 很重要的一个接口 完成BeanDefinition注册后调用接口可以对注册的BeanDefinition进行修改
* 完成对这两个接口的调用
*/
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

//把实现了BeanPostProcessor接口的类实例化,并且加入到BeanFactory中
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

//国际化,重要程度2
// Initialize message source for this context.
initMessageSource();

//初始化事件管理类
// Initialize event multicaster for this context.
initApplicationEventMulticaster();

//这个方法着重理解模板设计模式,因为在springboot中,这个方法是用来做内嵌tomcat启动的
// Initialize other special beans in specific context subclasses.
onRefresh();

//往事件管理类中注册事件类
// Check for listener beans and register them.
registerListeners();

/*
* 这个方法是spring中最重要的方法,没有之一
* 所以这个方法一定要理解要具体看
* 1、bean实例化过程
* 2、ioc
* 3、注解支持
* 4、BeanPostProcessor的执行
* 5、Aop的入口
*
* */
// 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():初始化应用的事件广播器。

registerListeners():注册监听器。

finishRefresh():完成上下文的刷新工作。

initApplicationEventMulticaster

初始化应用的事件广播器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* 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);
// 并将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() + "]");
}
}
}

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

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

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

registerListeners

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
* 注册监听器
*/
protected void registerListeners() {
// Register statically specified listeners first.
// 1.通过硬编码调用addApplicationListener方法添加的监听器处理(可以通过自定义ApplicationContextInitializer添加)
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}

//获取到实现了ApplicationListener接口的类的名称
// 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<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
//多播事件,事件执行
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}

​ 通过硬编码调用 addApplicationListener 方法添加的监听器处理,可以通过自定义 ApplicationContextInitializer 添加

finishRefresh

完成此上下文的刷新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* 完成此上下文的刷新
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
//1. 清除上下文级资源缓存
clearResourceCaches();

// Initialize lifecycle processor for this context.
// 2.为此上下文初始化生命周期处理器
initLifecycleProcessor();

// Propagate refresh to lifecycle processor first.
// 3.首先将刷新完毕事件传播到生命周期处理器(触发isAutoStartup方法返回true的SmartLifecycle的start方法)
getLifecycleProcessor().onRefresh();

// Publish the final event.
// 4.推送上下文刷新完毕事件到相应的监听器
publishEvent(new ContextRefreshedEvent(this));

// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}

initLifecycleProcessor

初始化生命周期处理器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* Initialize the LifecycleProcessor.
* Uses DefaultLifecycleProcessor if none defined in the context.
* 初始化生命周期处理器
*
* @see org.springframework.context.support.DefaultLifecycleProcessor
*/
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.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() + "]");
}
}
}

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

onRefresh

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@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<>();
// 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();
}
}
}

​ 这边讲下 autoStartupOnly 这个参数。

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

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

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

publishEvent

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}

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

使用事件广播器广播事件到相应的监听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 使用事件广播器广播事件到相应的监听器
*
* @param event
* @param eventType
*/
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
// 1.getApplicationListeners:返回与给定事件类型匹配的应用监听器集合
Executor executor = getTaskExecutor();
// 2.返回此广播器的当前任务执行程序
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
} else {
// 3.2 否则,直接调用监听器
invokeListener(listener, event);
}
}
}
invokeListener

用给定的事件调用给定的侦听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
* Invoke the given listener with the given event.
* 用给定的事件调用给定的侦听器
*
* @param listener the ApplicationListener to invoke
* @param event the current event to propagate
* @since 4.1
*/
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);
}
}

@SuppressWarnings({"rawtypes", "unchecked"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
// 触发监听器的onApplicationEvent方法,参数为给定的事件
listener.onApplicationEvent(event);
} catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
} else {
throw ex;
}
}
}

自定义监听器实现

如果我们想在 Spring IoC 容器构建完毕之后进行一些逻辑,就可以通过监听器来实现。

创建一个自定义监听器,实现 ApplicationListener 接口,监听 ContextRefreshedEvent(上下文刷新完毕事件),并且将该监听器注册到 Spring IoC 容器即可。

1
2
3
4
5
6
7
8
@Component
public class MyRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("ApplicationContext 启动完成");
}
}

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

​ 跟 ContextRefreshedEvent 相似的还有:ContextStartedEvent、ContextClosedEvent、ContextStoppedEvent,有兴趣的可以自己看看这几个事件的使用场景。

​ 当然,我们也可以自定义监听事件,只需要继承 ApplicationContextEvent 抽象类即可。

总结

本文主要介绍了几个用于扩展使用的功能:

  • ApplicationEventMulticaster:应用事件广播器,用于发布事件到相应的监听器。
  • LifecycleProcessor:生命周期处理器,用于处理生命周期事件。
  • Lifecycle:定义生命周期控制方法的接口,特别是 SmartLifecycle,可以在 Spring IoC 容器刷新完毕时进行触发。
  • ApplicationContextEvent:应用事件的基类。
  • ApplicationListener,应用事件监听器,用于监听应用事件。

评论