• 基于 ApplicationEvent 实现事件监听(进阶篇)


    基于 ApplicationEvent 实现事件监听(进阶篇)

    背景:

    	实现一个消息事件,需要同时发送短信通知和邮件通知,并且每个通知都是异步方式。
    
    • 1

    1. 事件类

    public class MyMessageEvent extends ApplicationEvent {
    
        private static final long serialVersionUID = -5481658020206295565L;
    
        private MyMessage msg;
    
        //谁发布的这个事件,souce就是谁(对象)
        public MyMessageEvent(Object source, MyMessage msg) {
            super(source);
            this.msg = msg;
        }
        public MyMessage getMsg() {
            return msg;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2. 抽象事件通知服务类

    在该类的 onApplicationEvent 方法上面添加 @Async ,同时需要在启动类上添加 @EnableAsync,实现异步通知。
    
    • 1
    @Slf4j
    @Service
    public abstract class MessageEvenService implements ApplicationListener<MyMessageEvent> {
    
    
        @Async
        @Override
        public void onApplicationEvent(MyMessageEvent event) {
            this.processMsg(event.getMsg());
        }
    
        protected abstract void processMsg(MyMessage msg);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3. 定义策略类(子类)

    3.1 邮件通知类

    @Slf4j
    @Component("emailMessage")
    public class EmailMessageImpl extends MessageEvenService {
    
        @Override
        public void processMsg(MyMessage msg) {
            log.info("Email 监听 处理消息:{}", JSONObject.toJSONString(msg));
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.2 短信通知类

    @Slf4j
    @Component("smsMessage")
    public class SMSMessageImpl extends MessageEvenService {
    
        @Override
        protected void processMsg(MyMessage msg) {
            log.info("SMS 监听 处理消息:{}", JSONObject.toJSONString(msg));
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4. 测试事件通知controller

    @RestController
    public class EventDemoController {
    
        @Autowired
        private EventDemoService eventDemoService;
    
    
        @GetMapping("/testEvent")
        public String testEvent() {
            eventDemoService.testEvent();
            return "OK";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5. 测试事件通知service

    @Service
    @Slf4j
    public class EventDemoServiceImpl implements EventDemoService {
    
        @Autowired
        private ApplicationEventPublisher applicationEventPublisher;
    
        @Override
        public void testEvent() {
            log.info("*********** 开始推送消息事件 ***********");
            MyMessage message = new MyMessage().setMessage("彩票中将啦").setMsgId("m123456").setNotifyId("u0000000");
            applicationEventPublisher.publishEvent(new MyMessageEvent(this, message));
            log.info("*********** 结束推送消息事件 ***********");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    6. 配置线程池

    @Configuration
    public class AsyncConfig {
        @Bean
        public TaskExecutor taskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            // 设置核心线程数
            executor.setCorePoolSize(5);
            // 设置最大线程数
            executor.setMaxPoolSize(10);
            // 设置队列容量
            executor.setQueueCapacity(20);
            // 设置线程活跃时间(秒)
            executor.setKeepAliveSeconds(60);
            // 设置默认线程名称
            executor.setThreadNamePrefix("user-rpt-");
            // 设置拒绝策略
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            // 等待所有任务结束后再关闭线程池
            executor.setWaitForTasksToCompleteOnShutdown(true);
            return executor;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    7. 测试效果

    浏览器访问 http://localhost:8888/demo/testEvent
    在这里插入图片描述

    8. 项目结构

    在这里插入图片描述

  • 相关阅读:
    常见的数码管中的引脚分布情况
    Android Aidl跨进程通讯(三)--进阶使用
    说一下 JVM 有哪些垃圾回收器?
    小学生python练习3--跳伞防鸟小游戏
    双十一怎么入手最划算,盘点几款不踩雷的好物推荐
    回溯算法(回溯搜索法)
    Spark Local模式的基本原理及部署
    Windows系统Mysql8版本的安装教程
    第四章黑盒测试
    Mybatis-Plus使用Wrapper自定义SQL
  • 原文地址:https://blog.csdn.net/qq_42610605/article/details/127769824