自定义事件
// 自定义一个事件类,继承自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的逻辑的,好像用处不太大;
其实对解耦代码有很大的帮助,比如多种业务场景做完都要插入通知消息,每个场景代码在做完业务逻辑,直接发布一个对应的事件,让监听器去处理监听逻辑即可,而不需要每个场景都加这一段代码。
另外插入消息的动作是不影响业务成功的;