观察者 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通常在以下情况中使用:

  1. 跨Bean的信息传递:当需要在不同的bean之间进行信息传递时,可以使用publishEvent。例如,beanA的事件处理完成后,需要通知beanB进行某些业务逻辑的处理。
  2. 业务逻辑解耦:通过publishEvent,可以将事件发布者和监听者解耦,使得事件发布者不需要知道具体的监听者是谁,只需要发布事件即可。这有助于降低代码之间的耦合度,提高代码的可维护性。
  3. 日志处理:publishEvent也可以用于日志处理,例如当某个事件发生时,可以发布一个事件,然后有专门的监听器来处理这个事件的日志记录。

在Spring框架中,ApplicationContext的事件处理是通过ApplicationEvent类和ApplicationListener接口来提供的。当需要发布事件时,可以调用ApplicationContextpublishEvent()方法,并传入一个ApplicationEvent对象。如果有对应的ApplicationListener监听了这个事件,那么就会收到通知并处理这个事件。

需要注意的是,如果需要开启异步操作,可以在@EventListener注解上增加@Async注解。这样,当事件发布后,监听器的处理将会在一个新的线程中进行,不会阻塞事件发布者的执行。

posted @ 2024-02-19 06:18  xiaoBai1001  阅读(23)  评论(0编辑  收藏  举报