说明
在最近项目开发中,需要在原有项目的基础上需要对原有部分业务数据添加监控功能。所以第一时间想到了使用监听器,事件触发机制解决。没想到在自定义事件和添加监听器功能后,测试代码出现了onApplicationEvent 事件被多次执行的问题。项目是 spring cloud,查阅资料说是由于有多个容器的原因。这里特别记录下解决方式。
1.自定义监听器
1.1 自定义事件
public class WayBillPlanEvent extends ApplicationEvent {
private String helloStr ="这是测试 监听器 事件定义内容 ";
public WayBillPlanEvent(Object source) {
super(source);
}
public String getHelloStr() {
return helloStr;
}
public void setHelloStr(String helloStr) {
this.helloStr = helloStr;
}
}
2. 定义监听器
@Component
public class WayBillPlanEventListener{
@Component
public class WayBillPlanEventListener implements ApplicationListener<WayBillPlanEvent> {
@Async
public void onApplicationEvent(WayBillPlanEvent wayBillPlanEvent) {
System.out.println("WayBillPlanEventListener : " + wayBillPlanEvent.getSource().toString() + wayBillPlanEvent.getHelloStr());
}
}
3.配置监听器
监听器配置有多种方式,这里通过 spring.factories 文件配置,
注意,文件路径为 \resources\META-INF\spring.factories
文件内容:
org.springframework.context.ApplicationListener=\
com.onitor.listeners.WayBillPlanEventListener
4. 发布事件
@Resource
private ApplicationContext applicationContext;
public void listenerNoticeServiceImpl(){
WayBillPlanEvent wayBillPlanEvent = new WayBillPlanEvent(this);
applicationContext.publishEvent(wayBillPlanEvent);
}
5. 启动项目测试结果
监听器的 onApplicationEvent 方法被执行了多次。
6. 处理方法
通过注解 @EventListener 可解决 onApplicationEvent 被执行多次的问题。注意通过 @EventListener 注解 需删除 \resources\META-INF\spring.factories 中 ApplicationListener 的配置。
代码
@Component
public class WayBillPlanEventListener{
@EventListener
@Async
public void onApplicationEvent(WayBillPlanEvent wayBillPlanEvent) {
System.out.println("WayBillPlanEventListener : " + wayBillPlanEvent.getSource().toString() + wayBillPlanEvent.getHelloStr());
}
}