观察者 PublishEvent
一、使用场景
这个一般什么时候使用,我们一般是在不同的bean直接进行信息传递,比如我们beanA的事件处理完后,需要beanB进行处理一些业务逻辑的时候这种情况就一般可以使用publish-event解决。
二、原理
ApplicationContext中的事件处理是通过ApplicationEvent类和ApplicationListener接口来提供的,通过ApplicationContext的publishEvent()方法发布到ApplicationListener;。
一个事件模型有三个组成部分:被监听对象source(也称为事件源),事件event和监听对象listener。事件发布者在发布事件的时候->通知事件的监听者。
首先,由监听对象注册监听回调函数(Callback),当事件源触发了事件后,监听对象会收到事件源的信息,然后决定如何对事件源进行处理,简要流程如下图所示。
三、事件触发 && 监听处理过程
(1) 使用 org.springframework.context 包下的 ApplicationContext.publishEvent(ApplicationEvent appEvent) 发布事件
(2) 使用 org.springframework.context.event 包下的 @EventListener(事件名) 监听事件并处理。
注意:
(1) ApplicationContext.publishEvent 默认是同步操作, 并非发布后不管的异步操作,发布事件后需要等 @EventListener 执行完。
(2) 如果需要开启异步操作需要在@EventListener上增加@Async 注解。
四、实例分为3部分 1、事件实体 2、事件监听 3、事件发布
1、 事件实体 /** * @Author:yanbo.li * @CreateTime: 2023-04-24 * @Description: 事件实体 */ @Data @AllArgsConstructor @NoArgsConstructor public class CustomerEvent { private String message; /** * 可以定义不同种类处理 */ private Integer eventType; }
2、事件监听
/** * 监听者 */ @Component public class CustomEventListener { @EventListener(CustomerEvent.class) public void onApplicationEvent(CustomerEvent customEvent) throws InterruptedException { System.out.println("监听器接受消息:"+ customEvent.getMessage()); } }
3、事件发布者
/** * 发布事件 * @return */ @RequestMapping("/publish") public String publishEvent() { CustomerEvent customerEvent = new CustomerEvent("发布事件了",1); applicationContext.publishEvent(customerEvent); return "success"; }
总结:
观察者模式中的publishEvent
通常在以下情况中使用:
- 跨Bean的信息传递:当需要在不同的bean之间进行信息传递时,可以使用
publishEvent
。例如,beanA的事件处理完成后,需要通知beanB进行某些业务逻辑的处理。 - 业务逻辑解耦:通过
publishEvent
,可以将事件发布者和监听者解耦,使得事件发布者不需要知道具体的监听者是谁,只需要发布事件即可。这有助于降低代码之间的耦合度,提高代码的可维护性。 - 日志处理:
publishEvent
也可以用于日志处理,例如当某个事件发生时,可以发布一个事件,然后有专门的监听器来处理这个事件的日志记录。
在Spring框架中,ApplicationContext
的事件处理是通过ApplicationEvent
类和ApplicationListener
接口来提供的。当需要发布事件时,可以调用ApplicationContext
的publishEvent()
方法,并传入一个ApplicationEvent
对象。如果有对应的ApplicationListener
监听了这个事件,那么就会收到通知并处理这个事件。
需要注意的是,如果需要开启异步操作,可以在@EventListener
注解上增加@Async
注解。这样,当事件发布后,监听器的处理将会在一个新的线程中进行,不会阻塞事件发布者的执行。