目录
概念
1.ApplicationEvent
2.ApplicationEventPublisher
3.ApplicationEventPublisherAware
4.ApplicationListener
具体使用
1.自定义事件MyEvent.java
2.自定义事件发布工具MyPublishAware.java
3.自定义两个事件监听器MyListenner.java(实现接口方式)和MyListennerTwo.java(注解方式)
参考文章
概念
事件的发布者发布事件,事件的监听者对对应的事件进行监听,当监听到对应的事件时,就会触发调用相关的方法。因此,在事件处理中,事件是核心,是事件发布者和事件监听者的桥梁。
Spring 是基于Observer模式(java.util包中有对应实现)提供了针对Bean的事件发布和订阅功能。
Spring中相关的主要有3个接口和1个抽象类:
public abstract class ApplicationEvent extends EventObject{ public interface ApplicationEventPublisher{ public interface ApplicationEventPublisherAware extends Aware{ public interface ApplicationListener<E extends ApplicationEvent> extends EventListener{
1.ApplicationEvent
ApplicationEvent继承自JavaSE中的EventObject,我们在使用的时候可以继承这个抽象类来定义事件,进行信息的传递,因为ApplicationListener只接受ApplicationEvent或者他的子类。
Spring自定义的ApplicationEvent实现类有很多:
其中:
1)ContextRefreshedEvent:当ApplicationContext初始化或者刷新时触发该事件。 2)ContextClosedEvent:当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。 3)ContestStartedEvent:当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。 4)ContestStopedEvent:当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。 5)ApplicationContextEvent 这个是平时经常用到的。
2.ApplicationEventPublisher
事件的发布接口,通过publishEvent(ApplicationEvent event)方法来发布消息。
3.ApplicationEventPublisherAware
通过这个接口的void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher)方法,将ApplicationEventPublisher注入进去,来进行消息通知。
4.ApplicationListener
监听器接口,ApplicationListener中的void onApplicationEvent(E event)来接收消息事件,进行消息处理。通过源代码发现,事件E需要是ApplicationEvent或者ApplicationEvent的子类。
具体使用
1.自定义事件MyEvent.java
package com.genertech.plm.aia.portaladmin.test; import org.springframework.context.ApplicationEvent; /** * @author: huo.qw * @createTime: 2024/01/16 下午 08:17 * @description: * @version: v1.0 */ public class MyEvent extends ApplicationEvent { // 也可以是对象等其它数据,也可以不传递数据 private String words; public MyEvent(Object source, String words) { super(source); this.words = words; } public String getWords() { return words; } public void setWords(String words) { this.words = words; } }
2.自定义事件发布工具MyPublishAware.java
// 不支持异步,sayHello()发布事件后会等待所有监听器执行完(多个监听器之间也是串行执行的)才会继续执行sayHello()以下的代码。
// 若要支持,可以在启动类加@EnableAsync,在监听器的onApplicationEvent方法、
// 或者@EventListener(MyEvent.class)标注的方法加@Async注解实现。
package com.genertech.plm.aia.portaladmin.test; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; /** * @author: huo.qw * @createTime: 2024/01/16 下午 08:33 * @description: * @version: v1.0 */ @Component @EnableScheduling // 开启定时任务 @Slf4j public class MyPublishAware implements ApplicationEventPublisherAware { private ApplicationEventPublisher applicationEventPublisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } public void sayHello(MyEvent myEvent) { this.applicationEventPublisher.publishEvent(myEvent); } // 通过定时任务来测试[发布事件] @Scheduled(fixedRate = 10000 * 1) public void tryTest() { MyEvent myEvent = new MyEvent(this, new String("hello World!")); sayHello(myEvent); // 不支持异步,sayHello()发布事件后会等待所有监听器执行完(多个监听器之间也是串行执行的)才会继续执行sayHello()以下的代码。 // 若要支持,可以在启动类加@EnableAsync,在监听器的onApplicationEvent方法、 // 或者@EventListener(MyEvent.class)标注的方法加@Async注解实现。 log.info(Thread.currentThread().getName()+"测试是否支持异步"); } }
3.自定义两个事件监听器MyListenner.java(实现接口方式)和MyListennerTwo.java(注解方式)
package com.genertech.plm.aia.portaladmin.test; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * @author: huo.qw * @createTime: 2024/01/16 下午 08:34 * @description: * @version: v1.0 */ @Component @Slf4j public class MyListenner implements ApplicationListener<MyEvent> { //如果实现的是implements ApplicationListener<ApplicationEvent>,则 //public void onApplicationEvent(ApplicationEvent e) {会监听到所有 //继承了ApplicationEvent抽象类的事件,其中包括MyEvent事件. @Override //@EventListener(MyEvent.class) public void onApplicationEvent(MyEvent e) { log.info(Thread.currentThread().getName()+"MyListennerOne订阅接收到的数据为:" + e.getWords()); try { Thread.sleep(5000L); } catch (InterruptedException interruptedException) { interruptedException.printStackTrace(); } } }
package com.genertech.plm.aia.portaladmin.test; import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; /** * @author: huo.qw * @createTime: 2024/01/17 下午 03:39 * @description: * @version: v1.0 */ @Component @Slf4j public class MyListennerTwo { @EventListener(MyEvent.class) public void methodName(MyEvent e) { log.info(Thread.currentThread().getName()+"MyListennerTwo订阅接收到的数据为:" + e.getWords()); try { Thread.sleep(5000L); } catch (InterruptedException interruptedException) { interruptedException.printStackTrace(); } } }
参考文章
Spring 事件发布订阅_spring事件发布订阅-CSDN博客
spring中的发布订阅_spring 订阅发布-CSDN博客
Spring Event事件用法 Spring Boot Event事件发布和订阅 Spring Event事件发布 Spring Event事件订阅_springboot 事件发布订阅-CSDN博客