一篇文章搞懂Spring Boot事件监听机制原理
一、前言
事件监听机制使用23种设计模式中的“观察者模式”,事件监听机制器的核心是广播器
org.springframework.context.event.SimpleApplicationEventMulticaster
二、事件监听器注册过程
1.ApplicationListener注册方式
- SPI方式注册ApplicationListener
- 静态listener
- ApplicationListener as a spring bean
- @EventListener process as a spring bean
2.SimpleApplicationEventMulticaster的初始化
=> SpringApplication run
org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...)
=> SpringApplication run
org.springframework.boot.SpringApplication#run(java.lang.String...)
=> 通过Spring SPI读取sping.factories中配置项
Run Listeners
(spring-boot)org.springframework.boot.SpringApplicationRunListener=org.springframework.boot.context.event.EventPublishingRunListener
org.springframework.boot.SpringApplication#getRunListeners
=> EventPublishingRunListener初始化
org.springframework.boot.context.event.EventPublishingRunListener#EventPublishingRunListener
=> 广播器SimpleApplicationEventMulticaster初始化
org.springframework.boot.context.event.EventPublishingRunListener#initialMulticaster
3.SPI方式注册ApplicationListener
=> SpringApplication run
org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...)
=> SpringApplication 初始化
org.springframework.boot.SpringApplication#SpringApplication(org.springframework.core.io.ResourceLoader, java.lang.Class<?>...)
=> 通过Spring SPI读取sping.factories中配置项
Application Listeners
(spring-boot 和 spring-boot-autoconfigure)
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
=> SimpleApplicationEventMulticaster静态监听器注册
org.springframework.boot.context.event.EventPublishingRunListener#EventPublishingRunListener
- 示例
# Application Listeners
org.springframework.context.ApplicationListener=\
com.example.demo.listener.MessageEventListener
4.静态listener和ApplicationListener as a spring bean
=> SpringApplication run
org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...)
=> SpringApplication run
org.springframework.boot.SpringApplication#run(java.lang.String...)
=> refreshContext
org.springframework.boot.SpringApplication#refreshContext
=> refresh
org.springframework.context.support.AbstractApplicationContext#refresh
=> registerListeners 注册静态listener和ApplicationListener Bean
org.springframework.context.support.AbstractApplicationContext#registerListeners
5.@EventListener process as a spring bean
=> SpringApplication run
org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...)
=> SpringApplication run
org.springframework.boot.SpringApplication#run(java.lang.String...)
=> 创建容器
org.springframework.boot.SpringApplication#createApplicationContext
=> 注册直接配置processer Bean
org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
=> 单例实例化完成后
org.springframework.context.event.EventListenerMethodProcessor#afterSingletonsInstantiated
=>
org.springframework.context.event.EventListenerMethodProcessor#processBean
三、事件发布
1.示例
@Service("eventService")
public class EventServiceImpl implements EventService, ApplicationEventPublisherAware {
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
@Override
public void publish() {
applicationEventPublisher.publishEvent(new MessageApplicationEvent("hello"));
}
}
2.ApplicationListener接口方式事件发布过程
- 直接或者间接实现
ApplicationListener
接口
直接实现
ApplicationListener
接口需要指定ApplicationEvent
类型,仅可以监听一种ApplicationEvent
类型;实现SmartApplicationListener
(间接实现ApplicationListener
接口)可以监听多种ApplicationEvent
类型。
=> 发布事件
org.springframework.context.support.AbstractApplicationContext#publishEvent(org.springframework.context.ApplicationEvent)
=> 事件广播器
org.springframework.context.event.SimpleApplicationEventMulticaster#multicastEvent(org.springframework.context.ApplicationEvent, org.springframework.core.ResolvableType)
=> 调用(默认直接调用即与调用者使用同一个线程,因此会阻塞调用者)
org.springframework.context.event.SimpleApplicationEventMulticaster#invokeListener
=> 调用
org.springframework.context.event.SimpleApplicationEventMulticaster#doInvokeListener
3.@EventListener方式事件发布过程
以
TransactionalEventListener
为例
同ApplicationListener接口方式事件发布过程方式
=> 监听适配器
org.springframework.transaction.event.TransactionalApplicationListenerMethodAdapter
=> 监听方法适配器
org.springframework.context.event.ApplicationListenerMethodAdapter#processEvent
参考: