使用ApplicationListener和ApplicationEvent完成结果通知
-
自定义事件
// 自定义一个事件类,继承自ApplicationEvent: public class AnnounceEvent extends ApplicationEvent { private String who; private String when; private String money; public AnnounceEvent (String who, String when, String money) { super(who + when + money); this.who = who; this.when = when; this.money = money; } @Override public String toString() { return "AnnounceEvent{" + "who='" + who + '\'' + ", when='" + when + '\'' + ", money='" + money + '\'' + '}'; } }
-
定义该事件的监听器
@Component public class AnnounceListener implements ApplicationListener<AnnounceEvent> { private Logger log = LoggerFactory.getLogger(AnnounceListener .class); @Override public void onApplicationEvent(AnnounceListener event) { log.info("收到通知, 正在处理..." + event); // 模拟处理逻辑 } }
-
在处理完退款业务逻辑后,推送通知
@RequestMapping("/event") @RestController public class EventController { private Logger log = LoggerFactory.getLogger(EventController.class); @Autowired ApplicationContext applicationContext; @RequestMapping("/publish") public String publish() { log.info("处理完...插入消息通知"); // 模拟业务操作 applicationContext.publishEvent(new AnnounceEvent ("welldone", "2022-01-01", "100")); // 推送事件 return "111"; } }
-
测试
请求该接口,当业务逻辑处理完后,推送AnnounceEvent 事件,监听器接收到事件后会去处理, 请求接口打印如下:
2022-12-03 21:13:56.299 INFO 225524 --- [nio-8080-exec-1] c.w.c.ext.event.ctl.EventController : 处理完业务逻辑...发布通知事件 2022-12-03 21:13:56.300 INFO 225524 --- [nio-8080-exec-1] c.w.c.e.event.listener.AnnounceListener : 收到通知, 正在处理...AnnounceEvent{who='welldone', when='2022-01-01', money='100'}
个人理解:
Spring的事件机制为Bean之间提供了传递消息的支持,当然这是在同一个进程中的;
ApplicationListener只能在本进程内进行通知,并且从日志看是使用当前线程去操作Listener的逻辑的,好像用处不太大;
其实对解耦代码有很大的帮助,比如多种业务场景做完都要插入通知消息,每个场景代码在做完业务逻辑,直接发布一个对应的事件,让监听器去处理监听逻辑即可,而不需要每个场景都加这一段代码。
另外插入消息的动作是不影响业务成功的;