java.util.Observablejava.util.Observerjava.util.EventObjectjava.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.ApplicationContextEventorg.springframework.context.event.ContextClosedEventorg.springframework.context.event.ContextRefreshedEventorg.springframework.context.event.ContextStartedEventorg.springframework.context.event.ContextStoppedEventJava 标准事件监听器 java.util.EventListener 扩展
org.springframework.context.ApplicationListeneronApplicationEvent(ApplicationEvent)org.springframework.context.ApplicationEventSpring 注解 - @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.ApplicationEventorg.springframework.context.ApplicationListenerorg.springframework.context.ApplicationListener 注册到容器内ApplicationEventPublisherAware 回调接口@Autowired ApplicationEventPublisher查找条件
applicationEventMulticasterBean 类型: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.ErrorHandlerSimpleApplicationEventMulticaster Spring 4.1 开始支持org.springframework.scheduling.concurrent.ConcurrentTaskSchedulerorg.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.ApplicationEventorg.springframework.context.ApplicationListenerorg.springframework.context.ApplicationEventPublisherorg.springframework.context.event.ApplicationEventMulticasterContextRefreshedEvent@EventListener 与 @Async 配合,实现异步处理,不阻塞主线程,比如长时间的数据计算任务等。不要轻易调整 SimpleApplicationEventMulticaster 中关联的 taskExecutor 对象,除非使用者非常了解 Spring 事件机制,否则容易出现异常行为。