文章目錄
- 1.執行個體代碼
- 2.源碼分析
- 2.1 添加後置處理器源碼解析
- 2.2 發送事件源碼分析
- 3.總結
1.執行個體代碼
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAnYldHL0FWby9mZvwFN4ETMfdHLkVGepZ2XtxSZ6l2clJ3LcV2Zh1Wa9M3clN2byBXLzN3btgHL9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsQTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SM4kTN5YTMxAzYxgTOwQWNzYzX1QzNwkTM5IzLcBTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
@Configuration
@ComponentScan("com.atguigu.event")
public class EventConfig {
}
監聽器
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
// 監聽器如何感覺到事件的:
// ApplicationEvent 和 Payload
// getApplicationEventMulticaster: 獲得多點傳播器, 發送事件
// 觀察者模式: 将所有的事件監聽器拿到, 矮個周遊, 調用onApplicationEvent()方法
// 事件派發: 周遊監聽器, 調用onApplicationEvent()方法
// 釋出事件觸發
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println(event);
}
}
服務代碼
@Component
public class UserService {
// EventListenerMethodProcessor, DefaultEventListenerFactory
// 後置處理和初始化
// SmartInitializingSingleton: 工廠後置處理環節, 執行增強和所有Bean完全建立好後執行初始化
// 後置增強環節: EventListenerMethodProcessor.postProcessBeanFactory(): 拿到所有的EventListenerFactory, 排序
// 初始化環節: afterSingletonsInstantiated():拿到容器中所有的元件, 處理這個元件
// 1.找到@EventListener 方法
// 2.周遊每一個方法: 拿到DefaultEventListenerFactory, 目前方法, beanName 封裝到擴充卡中ApplicationListenerMethodAdapter
// 工廠的作用為創造擴充卡: 擴充卡是一個監聽器, 多點傳播器注冊監聽器, 容器注冊監聽器, 事件派發給的是擴充卡, 擴充卡反射調用元件的事件監聽方法
// 标了@EventListener 注解, 就建立擴充卡, 擴充卡反射調用方法
// EventListenerMethodProcessor這個後置處理器為每一個監聽方法建立一個監聽器元件(擴充卡)
// 釋出器和監聽器
// 感覺的對象
@EventListener(classes = ApplicationEvent.class)
public void listener(ApplicationEvent event){
System.out.println("UserService : " + event);
}
}
主類
public class MainApplication {
public static void main(String[] args) {
/**
* 事件的釋出和監聽機制的原理:
* 擷取到EventMulticaster: 事件派發器
* 事件派發器: getApplicationEventMulticaster(): refresh(): initApplicationEventMulticaster()
* 容器中有哪些監聽器: refresh(): registerListener()
*
* @EventListener:
* EventListenerMethodProcessor->SmartInitializingSingleton, 單執行個體Bean建立完成後執行
*/
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
// 釋出事件
context.publishEvent(new ApplicationEvent("1") {
});
context.close();
// ContextRefreshedEvent,source,ContextClosedEvent
}
}
釋出事件
2.源碼分析
- 建立過程
- 運作過程
2.1 添加後置處理器源碼解析
添加後置處理器為建立過程
在ioc容器啟動(this()方法)的時候, 會加載EventListenerMethodProcessor 這個工廠後置處理器
這個後置處理器實作了
SmartInitializingSingleton
和
BeanFactoryPostProcessor
兩個接口
SmartInitializingSingleton
: 工廠後置處理環節, 執行增強和所有Bean完全建立好後執行初始化
- 後置增強環節: EventListenerMethodProcessor.postProcessBeanFactory(): 拿到所有的EventListenerFactory, 并排序
- 初始化環節: afterSingletonsInstantiated():拿到容器中所有的元件, 處理這個元件
postProcessBeanFactory: 拿到所有的EventListenerFactory, 并進行排序
afterSingletonsInstantiated: 拿到容器中所有的元件, 處理這個元件
processBean()
private void processBean(final String beanName, final Class<?> targetType) {
if (!this.nonAnnotatedClasses.contains(targetType) &&
AnnotationUtils.isCandidateClass(targetType, EventListener.class) &&
!isSpringContainerClass(targetType)) {
Map<Method, EventListener> annotatedMethods = null;
try {
annotatedMethods = MethodIntrospector.selectMethods(targetType,
(MethodIntrospector.MetadataLookup<EventListener>) method ->
AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
}
catch (Throwable ex) {
// An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
}
}
if (CollectionUtils.isEmpty(annotatedMethods)) {
this.nonAnnotatedClasses.add(targetType);
if (logger.isTraceEnabled()) {
logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
}
}
else {
// Non-empty set of methods
ConfigurableApplicationContext context = this.applicationContext;
Assert.state(context != null, "No ApplicationContext set");
List<EventListenerFactory> factories = this.eventListenerFactories;
Assert.state(factories != null, "EventListenerFactory List not initialized");
for (Method method : annotatedMethods.keySet()) {
for (EventListenerFactory factory : factories) {
if (factory.supportsMethod(method)) {
Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
ApplicationListener<?> applicationListener =
factory.createApplicationListener(beanName, targetType, methodToUse);
if (applicationListener instanceof ApplicationListenerMethodAdapter) {
((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
}
context.addApplicationListener(applicationListener);
break;
}
}
}
if (logger.isDebugEnabled()) {
logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
beanName + "': " + annotatedMethods);
}
}
}
}
拿到
DefaultEventListenerFactory
, 然後封裝進擴充卡中
- 找到@EventListener 方法
- 周遊每一個方法: 拿到DefaultEventListenerFactory, 目前方法, beanName 封裝到擴充卡中ApplicationListenerMethodAdapter
-
工廠的作用為創造擴充卡: 擴充卡是一個監聽器, 多點傳播器注冊監聽器, 容器注冊監聽器, 事件派發給的是擴充卡, 擴充卡反射調用元件的事件監聽方法。
标了@EventListener 注解, 就建立擴充卡, 擴充卡反射調用方法。
EventListenerMethodProcessor這個後置處理器為每一個監聽方法建立一個監聽器元件(擴充卡)
2.2 發送事件源碼分析
發送事件過程為運作事件過程
觀察者模式: for 循環
調用每一個監聽器的
onApplicationEvent
方法