Spring事件监听机制ApplicationEvent方式
作者:爱琴孩
前言
ApplicationEvent
以及 Listener
是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。
ApplicationEvent的小demo
ApplicationEvent本身是抽象类,无法直接实例化。一般通过子类继承ApplicationEvent
public class MyApplicationEvent extends ApplicationEvent { private Student student; public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public MyApplicationEvent(Object source) { super(source); } public MyApplicationEvent(Object source, Student student) { super(source); this.student = student; } }
事件定义好之后,我们注册个事件监听器即可。
实现ApplicationListener接口注册监听器
@Component public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> { private static final Logger LOGGER = LoggerFactory.getLogger(MyApplicationListener.class); @Override public void onApplicationEvent(MyApplicationEvent myApplicationEvent) { Student student = myApplicationEvent.getStudent(); LOGGER.info("学生对象是={}", JSONObject.toJSONString(student)); } }
通过@EventListener注册监听器,ApplicationContext.publishEvent 默认是同步操作, 并非发布后不管的异步操作,发布事件后需要等 @EventListener 执行完。
如果需要开启异步操作 需要在 @EventListener 上 增加 @Async 注解。
@Component public class AsyncApplicationListener { private static final Logger LOGGER = LoggerFactory.getLogger(AsyncApplicationListener.class); @EventListener @Async public void listener(MyApplicationEvent myApplicationEvent) { Student student = myApplicationEvent.getStudent(); LOGGER.info("通过@EventListener获取学生对象信息={}", JSONObject.toJSONString(student)); } }
通过实现SmartApplicationListener接口注册监听器
SmartApplicationListener接口继承了全局监听ApplicationListener,并且泛型对象使用的ApplicationEvent来作为全局监听,可以理解为使用SmartApplicationListener作为监听父接口的实现,监听所有事件发布。
既然是监听所有的事件发布,那么SmartApplicationListener接口添加了两个方法supportsEventType、supportsSourceType来作为区分是否是我们监听的事件,只有这两个方法同时返回true时才会执行onApplicationEvent方法。
@Component public class MySmartApplicationListener implements SmartApplicationListener { private static final Logger LOGGER = LoggerFactory.getLogger(MySmartApplicationListener.class); @Override public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) { return aClass == MyApplicationEvent.class; } @Override public boolean supportsSourceType(Class<?> sourceType) { return sourceType == ApplicationRunnerTest.class; } @Override public int getOrder() { return 0; } @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { MyApplicationEvent myApplicationEvent = (MyApplicationEvent) applicationEvent; LOGGER.info("通过MySmartApplicationListener 获取学生对象信息={}", JSONObject.toJSONString(myApplicationEvent.getStudent())); } }
可以看到除了上面的方法,还提供了一个getOrder方法,这个方法就可以解决执行监听的顺序问题,return的数值越小证明优先级越高,执行顺序越靠前
发布事件
在Spring的Bean中,注入ApplicationContext ,通过ApplicationContext 来进行事件发布
@Autowired private ApplicationContext applicationContext; applicationContext.publishEvent(new MyApplicationEvent(this, new Student("爱琴孩", 18)));
运行结果
2023-01-28 10:38:39.696 YYZX_Study 13540 [ main] INFO c.e.s.s.MySmartApplicationListener 37: 通过MySmartApplicationListener 获取学生对象信息={"age":18,"name":"爱琴孩"}
2023-01-28 10:38:39.696 YYZX_Study 13540 [ main] INFO c.e.study.service.MyApplicationListener 22: 学生对象是={"age":18,"name":"爱琴孩"}
2023-01-28 10:38:39.696 YYZX_Study 13540 [tOrderService-1] INFO c.e.s.service.AsyncApplicationListener 25: 通过@EventListener获取学生对象信息={"age":18,"name":"爱琴孩"}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。