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":"爱琴孩"}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服务的坑
这篇文章主要介绍了springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服务的坑,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-06-06springboot集成springsecurity 使用OAUTH2做权限管理的教程
这篇文章主要介绍了springboot集成springsecurity 使用OAUTH2做权限管理的教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-12-12
最新评论