Skip to content

Commit 23d9e3d

Browse files
committed
Spring-ApplicationListener.md
1 parent db9160a commit 23d9e3d

5 files changed

Lines changed: 246 additions & 0 deletions

File tree

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
# Spring initApplicationEventMulticaster
2+
- Author: [HuiFer](https://github.com/huifer)
3+
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
4+
5+
6+
7+
## demo
8+
9+
```java
10+
package com.huifer.source.spring.applicationListener;
11+
12+
import org.springframework.context.ApplicationEvent;
13+
import org.springframework.context.ApplicationListener;
14+
15+
public class DemoApplicationListener implements ApplicationListener {
16+
@Override
17+
public void onApplicationEvent(ApplicationEvent event) {
18+
System.out.println("com.huifer.source.spring.applicationListener.DemoApplicationListener.onApplicationEvent");
19+
}
20+
}
21+
22+
```
23+
24+
25+
26+
```XML
27+
<?xml version="1.0" encoding="UTF-8"?>
28+
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
29+
xmlns="http://www.springframework.org/schema/beans"
30+
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
31+
32+
<bean id="demoApplicationListener" class="com.huifer.source.spring.applicationListener.DemoApplicationListener"/>
33+
</beans>
34+
```
35+
36+
37+
38+
```JAVA
39+
public class ListenerSourceCode {
40+
public static void main(String[] args) {
41+
ApplicationContext context = new ClassPathXmlApplicationContext("Listener-demo.xml");
42+
}
43+
}
44+
```
45+
46+
47+
48+
## 初始化入口
49+
- `org.springframework.context.support.AbstractApplicationContext.refresh`中的`initApplicationEventMulticaster`方法
50+
51+
52+
53+
```java
54+
protected void initApplicationEventMulticaster() {
55+
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
56+
// 判断是否存在名字applicationEventMulticaster的bean
57+
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
58+
this.applicationEventMulticaster =
59+
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
60+
if (logger.isTraceEnabled()) {
61+
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
62+
}
63+
}
64+
else {
65+
// 创建一个
66+
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
67+
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
68+
if (logger.isTraceEnabled()) {
69+
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
70+
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
71+
}
72+
}
73+
}
74+
75+
```
76+
77+
78+
79+
## 注册
80+
81+
```JAVA
82+
protected void registerListeners() {
83+
// Register statically specified listeners first.
84+
// 读取 ApplicationListener
85+
for (ApplicationListener<?> listener : getApplicationListeners()) {
86+
getApplicationEventMulticaster().addApplicationListener(listener);
87+
}
88+
89+
// Do not initialize FactoryBeans here: We need to leave all regular beans
90+
// uninitialized to let post-processors apply to them!
91+
/**
92+
* 寻找类型为{@link ApplicationListener} 的beanName,目标文件为用户配置文件
93+
*/
94+
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
95+
for (String listenerBeanName : listenerBeanNames) {
96+
/**
97+
* 1. 获取 {@link applicationEventMulticaster}
98+
* 2. 添加监听器名称
99+
*/
100+
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
101+
}
102+
103+
// Publish early application events now that we finally have a multicaster...
104+
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
105+
this.earlyApplicationEvents = null;
106+
if (earlyEventsToProcess != null) {
107+
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
108+
getApplicationEventMulticaster().multicastEvent(earlyEvent);
109+
}
110+
}
111+
}
112+
113+
```
114+
115+
![image-20200119163638222](/images/spring/image-20200119163638222.png)
116+
117+
118+
119+
## finishRefresh 发布
120+
121+
```java
122+
protected void finishRefresh() {
123+
// Clear context-level resource caches (such as ASM metadata from scanning).
124+
clearResourceCaches();
125+
126+
// Initialize lifecycle processor for this context.
127+
initLifecycleProcessor();
128+
129+
// Propagate refresh to lifecycle processor first.
130+
getLifecycleProcessor().onRefresh();
131+
132+
// Publish the final event.
133+
// 发布事件做处理
134+
publishEvent(new ContextRefreshedEvent(this));
135+
136+
// Participate in LiveBeansView MBean, if active.
137+
LiveBeansView.registerApplicationContext(this);
138+
}
139+
140+
```
141+
142+
- `org.springframework.context.support.AbstractApplicationContext#publishEvent(org.springframework.context.ApplicationEvent)`
143+
- `org.springframework.context.support.AbstractApplicationContext#publishEvent(java.lang.Object, org.springframework.core.ResolvableType)`
144+
145+
146+
147+
148+
149+
```java
150+
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
151+
Assert.notNull(event, "Event must not be null");
152+
153+
// Decorate event as an ApplicationEvent if necessary
154+
ApplicationEvent applicationEvent;
155+
if (event instanceof ApplicationEvent) {
156+
applicationEvent = (ApplicationEvent) event;
157+
}
158+
else {
159+
applicationEvent = new PayloadApplicationEvent<>(this, event);
160+
if (eventType == null) {
161+
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
162+
}
163+
}
164+
165+
// Multicast right now if possible - or lazily once the multicaster is initialized
166+
if (this.earlyApplicationEvents != null) {
167+
this.earlyApplicationEvents.add(applicationEvent);
168+
}
169+
else {
170+
/**
171+
* 执行监听事件
172+
* {@link ApplicationEventMulticaster} ->{@link SimpleApplicationEventMulticaster}
173+
*/
174+
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
175+
}
176+
177+
// Publish event via parent context as well...
178+
if (this.parent != null) {
179+
if (this.parent instanceof AbstractApplicationContext) {
180+
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
181+
}
182+
else {
183+
this.parent.publishEvent(event);
184+
}
185+
}
186+
}
187+
```
188+
189+
190+
191+
- 执行监听方法
192+
193+
![image-20200119164149650](/images/spring/image-20200119164149650.png)
194+
195+
196+
197+
```java
198+
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
199+
ErrorHandler errorHandler = getErrorHandler();
200+
if (errorHandler != null) {
201+
try {
202+
doInvokeListener(listener, event);
203+
}
204+
catch (Throwable err) {
205+
errorHandler.handleError(err);
206+
}
207+
}
208+
else {
209+
doInvokeListener(listener, event);
210+
}
211+
}
212+
213+
```
214+
215+
216+
217+
```java
218+
@SuppressWarnings({"rawtypes", "unchecked"})
219+
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
220+
try {
221+
// 最后调用方法
222+
listener.onApplicationEvent(event);
223+
}
224+
catch (ClassCastException ex) {
225+
String msg = ex.getMessage();
226+
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
227+
// Possibly a lambda-defined listener which we could not resolve the generic event type for
228+
// -> let's suppress the exception and just log a debug message.
229+
Log logger = LogFactory.getLog(getClass());
230+
if (logger.isTraceEnabled()) {
231+
logger.trace("Non-matching event type for listener: " + listener, ex);
232+
}
233+
}
234+
else {
235+
throw ex;
236+
}
237+
}
238+
}
239+
240+
```
241+
242+
243+
244+
![image-20200119164402137](/images/spring/image-20200119164402137.png)
245+
246+
![image-20200119164410301](/images/spring/image-20200119164410301.png)
35.2 KB
Loading
60.2 KB
Loading
28.8 KB
Loading
18.5 KB
Loading

0 commit comments

Comments
 (0)