Spring事件Application Event
Spring 的事件(Application Event)为 Bean 与 Bean 之间的消息通信提供了支持。当一个 Bean 处理完一个任务之后,希望另一个 Bean 知道并能做相应的处理,这时我们就需要让另一个 Bean 监听当前 Bean 所发送的事件。(观察者模式) Spring 的事件需要遵循以下流程:
自定义事件,继承 ApplicationEvent。
定义事件监听器,实现 ApplicationListener。
使用容器发布事件。
什么是ApplicationContext? 它是Spring的核心,Context我们通常解释为上下文环境,但是理解成容器会更好些。 ApplicationContext则是应用的容器。
Spring把Bean(object)放在容器中,需要用就通过get方法取出来。
ApplicationEvent
是个抽象类,里面只有一个构造函数和一个长整型的timestamp。
ApplicationListener
是一个接口,里面只有一个onApplicationEvent方法。
所以自己的类在实现该接口的时候,要实装该方法。
如果在上下文中部署一个实现了ApplicationListener接口的bean,
那么每当在一个ApplicationEvent发布到 ApplicationContext时, 这个bean得到通知。其实这就是标准的Observer设计模式
一、如何使用?
1、 建立event
|
|
BookingCreatedEvent需要继承ApplicationEvent。
2、建立listener
|
|
BookingEventsListener 需要实现ApplicationListener 并重写onApplicationEvent方法。ApplicationListener带泛型,如果泛型参数为BookingCreatedEvent,则表示只监听BookingCreatedEvent类型的事件,如果泛型参数为ApplicationEvent ,则表示监听所有类型的事件。另外可以用@Component来注册组件,这样就不需要在spring的配置文件中指定了。
3、触发event
|
|
触发要实现ApplicationContextAware,用于引入ApplicationContext,由于bookingService也 是spring组件,所以在系统启动的时候,ApplicationContext已经注入。也可以用如下方式直接注入 ApplicationContext。
|
|
二、有什么好处?
解耦:
如上例子,如果客人booking了hotel以后,系统要发email给客人,那我们就可以在listener的do something处加上发送email的代码。
上面我们讲用@Component把listener注册成了spring的组件,这样listener的用途是在runtime的时候解耦。而如果我们把listener用配置文件的方式注册的话,主要用途是在部署的时候解耦。在实际应用中,两种情况都有。
另外要注意的一点是,service和listener是同步的,在service中的persistBooking有注册 @Transactional的情况下,listener中的do something和service中的persistBooking是在同一个tansaction下。
如果要做异步,需要通过MQ或者数据库中转。
附录
作者:守住阳光 链接:https://www.jianshu.com/p/e450cded3306