java.util.Observable
java.util.Observer
java.util.EventObject
java.util.EventListener
事件/监听器场景举例
Java 技术规范 | 事件接口 | 监听器接口 |
---|---|---|
JavaBeans | java.beans.PropertyChangeEvent |
java.beans.PropertyChangeListener |
Java AWT | java.awt.event.MouseEvent |
java.awt.event.MouseListener |
Java Swing | javax.swing.event.MenuEvent |
javax.swing.event.MenuListener |
Java Preference | java.util.prefs.PreferenceChangeEvent |
java.util.prefs.PreferenceChangeListener |
事件/监听器注解场景举例
Java 技术规范 | 事件注解 | 监听器注解 |
---|---|---|
Servlet 3.0+ | @javax.servlet.annotation.WebListener |
|
JPA 1.0+ | @javax.persistence.PostPersist |
|
Java Common | @PostConstruct |
|
EJB 3.0+ | @javax.ejb.PrePassivate |
|
JSF 2.0+ | @javax.faces.event.ListenerFor |
org.springframework.context.ApplicationEvent
Java 标准事件java.util.EventObject
扩展
扩展特性:事件发生时间戳
Spring 应用上下文ApplicationEvent
扩展 -ApplicationContextEvent
org.springframework.context.event.ApplicationContextEvent
org.springframework.context.event.ContextClosedEvent
org.springframework.context.event.ContextRefreshedEvent
org.springframework.context.event.ContextStartedEvent
org.springframework.context.event.ContextStoppedEvent
Java 标准事件监听器 java.util.EventListener
扩展
org.springframework.context.ApplicationListener
onApplicationEvent(ApplicationEvent)
org.springframework.context.ApplicationEvent
Spring 注解 - @org.springframework.context.event.EventListener
特性 | 说明 |
---|---|
设计特点 | 支持多 ApplicationEvent 类型,无需接口约束 |
注解目标 | 方法 |
是否支持异步执行 | 支持 |
是否支持泛型类型事件 | 支持 |
是指支持顺序控制 | 支持,配合 @Order 注解控制 |
ApplicationListener
作为 Spring Bean 注册ConfigurableApplicationContext#addApplicationListener
API 注册@org.springframework.context.event.EventListener
发布 Spring 事件
获取 ApplicationEventPublisher
方法二:通过 ApplicationEventMulticaster
发布 Spring 事件
获取 ApplicationEventMulticaster
依赖查找
ApplicationContext
发起 Spring 事件可能会传递到其 Parent ApplicationContext
(直到 Root)的过程ApplicationContextEvent
派生事件
ContextRefreshedEvent
:Spring 应用上下文就绪事件ContextStartedEvent
:Spring 应用上下文启动事件ContextStoppedEvent
:Spring 应用上下文停止事件ContextClosedEvent
:Spring 应用上下文关闭事件Spring Payload 事件 - org.springframework.context.PayloadApplicationEvent
ApplicationEventPublisher#publishEvent(java.lang.Object)
org.springframework.context.ApplicationEvent
org.springframework.context.ApplicationListener
org.springframework.context.ApplicationListener
注册到容器内ApplicationEventPublisherAware
回调接口@Autowired ApplicationEventPublisher
applicationEventMulticaster
org.springframework.context.event.ApplicationEventMulticaster
AbstractApplicationContext#earlyApplicationEvents 在 prepareRefresh() 中从 null 被赋值,在 registerListeners() 的最后,重新被赋值为 null,并进行了早期事件的发布,
因为可能存在一个 Bean 同时实现 BeanPostProcessor 和 ApplicationEventPublisherAware,并在 ApplicationEventPublisherAware#setApplicationEventPublisher 方法中发送事件
因为实现了 BeanPostProcessor,所以这个 Bean 在 registerBeanPostProcessors(beanFactory); 这个方法中初始化,而此时 initApplicationEventMulticaster(); 还没有执行,所以 AbstractApplicationContext#applicationEventMulticaster 为空,无法发布事件,所以先将事件保存在 AbstractApplicationContext#earlyApplicationEvents 中
接口:org.springframework.context.event.ApplicationEventMulticaster
抽象类:org.springframework.context.event.AbstractApplicationEventMulticaster
实现类:org.springframework.context.event.SimpleApplicationEventMulticaster
基于实现类 -org.springframework.context.event.SimpleApplicationEventMulticaster
方法
异步模式:如 java.util.concurrent.ThreadPoolExecutor
设计缺陷:不是基于接口契约编程,实现依赖于类本身
基于注解 -@org.springframework.context.event.EventListener
@org.springframework.scheduling.annotation.Async
区别:
SimpleApplicationEventMulticaster#setTaskExecutor
的影响是全局的,使用 @Async
是局部的SimpleApplicationEventMulticaster#setTaskExecutor
需要手动关闭线程池,使用 @Async
不需要org.springframework.util.ErrorHandler
SimpleApplicationEventMulticaster
Spring 4.1 开始支持org.springframework.scheduling.concurrent.ConcurrentTaskScheduler
org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
核心类 -org.springframework.context.event.SimpleApplicationEventMulticaster
设计模式:观察者模式扩展
被观察者 -org.springframework.context.ApplicationListener
通知对象 - org.springframework.context.ApplicationEvent
执行模式:同步/异步
异常处理:org.springframework.util.ErrorHandler
泛型处理:org.springframework.core.ResolvableType
事件类型 | 发生时机 |
---|---|
ApplicationStartingEvent | 当 Spring Boot 应用已启动时 |
ApplicationStartedEvent | 当 Spring Boot 应用已启动时 |
ApplicationEnvironmentPreparedEvent | 当 Spring Boot Environment 实例已准备时 |
ApplicationPreparedEvent | 当 Spring Boot 应用预备时 |
ApplicationReadyEvent | 当 Spring Boot 应用完全可用时 |
ApplicationFailedEvent | 当 Spring Boot 应用启动失败时 |
事件类型 | 发生时机 |
---|---|
EnvironmentChangeEvent | 当 Environment 示例配置属性发生变化时 |
HeartbeatEvent | 当 Discoveryclient 客户端发送心跳时 |
InstancePreRegisteredEvent | 当服务实例注册前 |
InstanceRegisteredEvent | 当服务实例注册后 |
RefreshEvent | 当 RefreshEndpoint 被调用时 |
RefreshScopeRefreshedEvent | 当 Refresh Scope Bean 刷新后 |
org.springframework.context.ApplicationEvent
org.springframework.context.ApplicationListener
org.springframework.context.ApplicationEventPublisher
org.springframework.context.event.ApplicationEventMulticaster
ContextRefreshedEvent
@EventListener
与 @Async
配合,实现异步处理,不阻塞主线程,比如长时间的数据计算任务等。不要轻易调整 SimpleApplicationEventMulticaster
中关联的 taskExecutor
对象,除非使用者非常了解 Spring 事件机制,否则容易出现异常行为。