SpringBoot中处理ApplicationContextEvent和自定义ApplicationEvent

在 Spring 框架中,事件处理是 Spring 组件以松散耦合方式相互通信的一项基本功能。任何 Spring 组件都可以发布事件,而其他组件则可以接收和响应事件。

事件发布组件需要 ApplicationEventPublisher 来发布来自组件的事件。它可以通过实现 ApplicationEventPublisherAware 接口或通过构造函数、设置方法和字段注入提供给组件。

事件接收器组件需要实现 ApplicationListener 接口或使用方法级注解 @EventListener 来接收发布的事件。

本教程的重点是使用注解简洁、方便地处理事件。

创建自定义事件
在 Spring 框架中,事件是通过扩展 ApplicationEvent 类创建的。

现在,让我们创建两个自定义事件,如下所示。

public class MessageEvent extends ApplicationEvent {

 private String message;

 public MessageEvent(Object source, String message) {
   super(source);
   this.message = message;
 }

 //Getter method
}

MessageEvent 将用于从发布者组件发布。

public class MessageResponseEvent extends ApplicationEvent {
 private final int responseCode;
 private final String responseMessage;

 public MessageResponseEvent(Object source, int responseCode, String responseMessage) {
   super(source);
   this.responseCode = responseCode;
   this.responseMessage = responseMessage;
 }

 // Getter methods
}

MessageResponseEvent 用于发布事件处理程序/接收器组件处理 MessageEvent 的结果。

发布自定义事件
要从组件中发布事件,我们需要 ApplicationEventPublisher。如下图所示,它可以通过构造函数注入到组件中。

@Component
public class MessageSenderService {

 private ApplicationEventPublisher applicationEventPublisher;

 public MessageSenderService(ApplicationEventPublisher applicationEventPublisher) {
   this.applicationEventPublisher = applicationEventPublisher;
 }

 //...
}

然后,我们可以使用 publishEvent() 方法来发布事件。

@Component
public class MessageSenderService {

 private ApplicationEventPublisher applicationEventPublisher;

 //...
 public void sendMessage(String message) {
   applicationEventPublisher.publishEvent(new MessageEvent(this, message));
 }

}

接收和处理自定义事件
要在 bean 中接收发布的事件,我们可以使用方法级注解 @EventListener。此注解将方法标记为监听器。

现在,创建一个事件处理程序,如下所示。

@Component
public class MessageReceiverService {

 @EventListener
 public MessageResponseEvent handleMessageEvent(MessageEvent event) {
   System.out.println("MessageEvent received : " + event.getMessage());
   return new MessageResponseEvent(this, 200,
"Message received");
 }
}

@EventListener 方法可以发布新事件 MessageResponseEvent,只需返回新事件即可,如上面的代码片段所示。

同样,我们可以使用 @EventListener 在任何 Bean 中接收 MessageResponseEvent,如下所示。

@EventListener
public void handleMessageEvent(MessageResponseEvent event) {
 System.out.println("MessageResponseEvent received : ");
 System.out.println(
"ResponseCode=" + event.getResponseCode());
 System.out.println(
"Message =" + event.getResponseMessage());
}

ApplicationContext 生命周期事件
在 Spring 中,ApplicationContext 的整个生命周期都会发布某些上下文事件。其中一些事件是

  • ContextStartedEvent - 该事件在 ApplicationContext 启动时发布。
  • ContextRefreshedEvent - 此事件在初始化或刷新 ApplicationContext 时发布。
  • ContextClosedEvent - 应用程序上下文关闭时发布此事件。
  • ContextStoppedEvent - 该事件在 ApplicationContext 停止时发布。

所有这些事件都是 ApplicationContextEvent 的子类,而 ApplicationContextEvent 本身则扩展了 ApplicationEvent。

使用 @EventListener 处理 ApplicationContextEvent 事件
与处理自定义事件类似,我们也可以使用 @EventListener 注解来处理 ApplicationContextEvent 事件。

下面是一个处理 ApplicationContextEvent 事件的示例。

@EventListener
public void handleEvent(ContextStartedEvent event) {
 System.out.println("ContextStartedEvent received");
}

通过使用 @EventListner 注解指定事件类型,事件处理程序方法可以处理多个事件,如下所示。

@EventListener(value = {ContextRefreshedEvent.class, ContextStartedEvent.class})
public void handleEvent() {
 //...
}

要异步处理事件,我们可以使用 @Async 注解和 @EventListener 注解,如下所示。

@EventListener
@Async
public void handleEvent(ContextClosedEvent event) {
 //...
}

结论
在本教程中,我们探讨了如何在 Spring 应用程序中发布和监听自定义事件。我们还深入研究了在 ApplicationContext 生命周期中发布的标准事件。此外,我们还介绍了 @EventListner 注解的各种功能。