使用场景
要接受消息进行存库操作,但是消息的来源是不固定的,有多个来源,触发的事件也是不固定的,最简单的一种方式是通过写接口然后二次调接口的方式来实现,但是这样又相当于多了一次操作,性能会降低,所以通过事件监听的方式来进行。
Event组成部分
完成一个完整的Event操作需要有三个部分:事件、事件监听器、事件发布器
示例
1、首先如果我们需要先定义一个事件,这里我们定义一个MessageEvent事件。需要继承Spring提供的ApplicationEvent类,这个类继承了JDK中的事件基类EventObject。因而自定义事件除了需要继承Application之外,还需要传入事件源作为构造参数(可进行重写)。
2、定义完事件之后我们需要定义事件发布者,也就是什么时候调用事件,Spring4.2之前需要实现ApplicationEventPublishAware,在Spring4.2之后,ApplicationEventPublishAware被自动注入到容器中,不在需要显示实现Aware接口,如下:
3、最后我们定义事件的订阅者(消费方)
事件订阅者的服务也是需要托管于Spring容器,ApplicationListener接口是Spring提供的事件订阅者必须实现的接口。如下:
如何实现通知监听?
首先,事件发布者调用了ApplicationEventPublisher(ApplicationEvent event)方法,来进行事件的发布。
所以我们先进入publishEvent方法看一下
在这个方法中,首先判断传入的事件是不是一个ApplicationEvent对象,如果不是,则将其包装成PayloadApplicationEvent事件,并获取对应的事件类型。
最后通过applicationEventMulticaster,调用multicastEvent方法来广播出去,下面我们看一下multicastEvent方法:
可以看到,该方法获取SimpleApplicationEventMulticaster中的线程执行器,如果存在线程执行器则在新线程中异步执行,否则直接同步执行监听器中的方法invokeListener。
在invokeListener方法中,如果存在ErrorHandler,则调用监听器方法,如果抛出异常则调用ErrorHandler来处理异常。否则直接调用监听器方法。
doInvokeListener就是执行监听器方法了:
之前说到,publishEvent方法有一个getApplicationEventMulticaster()方法来获取广播器ApplicationEventMulticaster,然后调用广播器的multicastEvent方法来广播出去。那么这个广播器是什么时候建立的呢?
applicationEventMulticaster在Spring的启动过程中被建立,在启动的核心方法refresh中,会建立applicationEventMulticaster:
这里的initApplicationEventMulticaster()用于在Spring容器中初始化事件广播器,用于事件的发布。
而registerListeners()用于把Spring容器内的事件监听器和BeanFactory中的事件监听器都添加进事件广播器中。
initApplicationEventMulticaster方法:
在该方法中,如果用户手动新建了一个名为applicationEventMulticaster类型为ApplicationEventMulticaster的bean,则将这个bean作为事件广播器,否则新建一个SimpleApplicationEventMulticaster作为默认的广播器。
registerListeners方法:
这个注册监听器方法,首先把提前存储好的监听器添加到监听器容器中,然后获取类型是ApplicationListener的beanName集合,但不会去实例化bean。如果存在earlyEventsToProcess,则提前处理这些事件。
致谢
参考博客:
https://blog.csdn.net/qq_34651490/article/details/108726799