spring 中的事件监听机制是运用观察者模式来实现的,观察者模式的优点有:
1、观察者和被观察者之间低耦合,代码比较好维护
2、被观察者和观察者之间是一对多的关系(当然也可以一对一),当被观察者状态改变的时候,多个观察者能同时进行处理,能实现广播通讯
观察者模式有两种角色:
1、Subject 目标角色:接收外界的状态变化,向观察者发送通知(广播通知)
2、Observer 观察者角色:就是具体操作的一个实体,根据Subject状态变化,会触发自身的具体操作逻辑
所以说subject 和 observer之间是一对多的关系
现在我们用spring监听机制来实现上述图示:
observer1,observer2,observer3监听subject1的状态变化
observer3,observer4监听subject2的状态变化
可见observer3同时可以监听subject1,subject2的状态变化
Subject1:声明事件1,Object source是通信传输数据的实体
- /**
- * @Author yangcai
- * @create 2022/6/24 15:47
- */
- public class Subject1 extends ApplicationEvent {
-
- public Subject1(Object source) {
- super(source);
- }
- }
Subject2:声明事件2,Object source是通信传输数据的实体
- /**
- * @Author yangcai
- * @create 2022/6/24 15:47
- */
- public class Subject2 extends Subject1 {
- public Subject2(Object source) {
- super(source);
- }
- }
EventPublisher:事件发布器,给监听器发送通知,触发监听器的执行
- @Component
- @Slf4j
- public class EventPublisher implements ApplicationEventPublisherAware {
-
- private ApplicationEventPublisher eventPublisher;
-
- public void publish(ApplicationEvent event) {
- eventPublisher.publishEvent(event);
- }
-
- @Override
- public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
- this.eventPublisher = applicationEventPublisher;
- }
-
- }
- @Data
- public class SourceEntity {
- private String subjectName;
- private String notifyMsg;
- }
ObserverEventHandler 声明监听器及监听的事件,多个监听器可以监听一个事件
- /**
- * @Author yangcai
- * @create 2022/6/24 15:48
- */
- @Slf4j
- @Component
- @RequiredArgsConstructor
- public class ObserverEventHandler {
-
- @EventListener(id="observer1",condition = "@listenerPredicate.test(#event)")
- public void handle1(Subject1 event) {
- SourceEntity sourceEntity = (SourceEntity)event.getSource();
- log.info("--observer1---handle1-----"+sourceEntity.getSubjectName());
- }
- @EventListener(id="observer2",condition = "@listenerPredicate.test(#event)")
- public void handle2(Subject1 event) {
- SourceEntity sourceEntity = (SourceEntity)event.getSource();
- log.info("--observer2---handle2-----"+sourceEntity.getSubjectName());
- }
- @EventListener(id="observer3")
- public void handle3(Subject1 event) {
- SourceEntity sourceEntity = (SourceEntity)event.getSource();
- log.info("--observer3---handle3-----"+sourceEntity.getSubjectName());
- }
-
- @EventListener(id="observer4")
- public void handle4(Subject2 event) {
- SourceEntity sourceEntity = (SourceEntity)event.getSource();
- log.info("--observer4---handle4-----"+sourceEntity.getSubjectName());
- }
- }
监听器监听事件的条件匹配器,可以根据通信实体中的数据,当事件被发布时,来进行判断当前监听器是否会触发执行
- /**
- * @Author yangcai
- * @create 2022/6/28 16:20
- */
- @Component
- public class ListenerPredicate implements Predicate<ApplicationEvent> {
- @Override
- public boolean test(ApplicationEvent event) {
- SourceEntity sourceEntity = (SourceEntity)event.getSource();
- if(event instanceof Subject2 && "subject2".equals(sourceEntity.getSubjectName())){
- return false;
- }
- return true;
- }
- }
测试subject1:
- @SpringBootApplication
- public class Stu1Application {
-
- public static void main(String[] args) throws InterruptedException {
- ApplicationContext ac = SpringApplication.run(Stu1Application.class, args);
- SubjectPublisher eventPublisher = ac.getBean(SubjectPublisher.class);
- SourceEntity sourceEntity = new SourceEntity();
- sourceEntity.setSubjectName("subject1");
- eventPublisher.publish(new Subject1(sourceEntity));
- }
- }
结果:
测试subject2:
- @SpringBootApplication
- public class Stu1Application {
-
- public static void main(String[] args) throws InterruptedException {
- ApplicationContext ac = SpringApplication.run(Stu1Application.class, args);
- SubjectPublisher eventPublisher = ac.getBean(SubjectPublisher.class);
- SourceEntity sourceEntity = new SourceEntity();
- sourceEntity.setSubjectName("subject2");
- eventPublisher.publish(new Subject2(sourceEntity));
- }
- }
结果:
配置监听器异步执行:需要新增两个配置文件
- /**
- * @Author yangcai
- * @create 2022/6/24 15:57
- */
- @Configuration
- public class ApplicationEventAsyncConfig {
-
- @Resource
- private ThreadPoolTaskExecutor myExecutor;
-
- @Bean
- public ApplicationEventMulticaster applicationEventMulticaster() { //@1
- //创建一个事件广播器
- SimpleApplicationEventMulticaster result = new SimpleApplicationEventMulticaster();
- //设置异步执行器,来完成异步执行监听事件这样会导致所有的监听器都异步执行
- result.setTaskExecutor(myExecutor);
- return result;
- }
- }
- @Configuration
- public class ThreadPoolConfig {
-
- @Bean("myExecutor")
- public Executor taskExecutor() {
- ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
- //设置线程池参数信息
- taskExecutor.setCorePoolSize(8);
- taskExecutor.setMaxPoolSize(20);
- taskExecutor.setQueueCapacity(50);
- taskExecutor.setKeepAliveSeconds(60);
- taskExecutor.setThreadNamePrefix("eventHandle--");
- taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
- // 设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住。
- taskExecutor.setAwaitTerminationSeconds(60);
- //修改拒绝策略为使用当前线程执行
- taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
- //初始化线程池
- taskExecutor.initialize();
- return taskExecutor;
- }
- }