SpringBoot事件发布及订阅详解含代码示例(值得珍藏)

点击下载《SpringBoot事件发布及订阅详解含代码示例(值得珍藏)》

1. 简介

1.1 ApplicationEvent

ApplicationEvent 是 Spring 框架中的一个重要概念,它是基于观察者模式的事件。简单来说,它是一个用于在 Spring 应用程序上下文中传播信息的对象。当某个特定的事件发生时,ApplicationEvent 对象会被创建并发布到 ApplicationContext 中,所有注册监听该事件的监听器就会收到通知并执行相应的操作。

ApplicationEvent 是一个泛型类,可以用来传递任何类型的数据。当事件被发布时,所有注册的监听器将会接收到一个 ApplicationEvent 对象,通过该对象的 getSource() 方法可以获取到事件源,即触发事件的组件。同时,通过 getTimestamp() 方法可以获取到事件发生的时间戳。

public class MyCustomEvent extends ApplicationEvent {  
    private String message;  
  
    public MyCustomEvent(Object source, String message) {  
        super(source);  
        this.message = message;  
    }  
  
    public String getMessage() {  
        return message;  
    }  
}

1.2 ApplicationListener

ApplicationListener 是 Spring 框架中的一个接口,用于监听容器中发布的事件。这个接口定义了一个方法:void onApplicationEvent(E event),当某个 ApplicationEvent 被发布时,所有注册监听该事件的 ApplicationListener 将会被调用。

ApplicationListener 是一个泛型接口,其参数 E 代表事件的类型。开发者需要实现这个接口,并指定要监听的事件类型。例如,如果要监听 CustomEvent 类型的事件,可以创建一个实现了 ApplicationListener 接口的类。

public interface ApplicationListener<E extends ApplicationEvent> {  
    void onApplicationEvent(E event);  
}

1.3 @EventListener

@EventListener 是一个 Spring 框架提供的注解,用于实现事件驱动编程。它允许定义事件和事件监听器,当事件被触发时,所有注册监听该事件的监听器将会被调用。

2. 使用示例

2.1 监听事件

2.1.1 使用ApplicationListener

要监听事件,需要实现 ApplicationListener 接口,并指定要监听的事件类型。然后,可以将这个监听器注册到 ApplicationContext 中。

@Component  
public class MyCustomEventListener implements ApplicationListener<MyCustomEvent> {  
    @Override  
    public void onApplicationEvent(MyCustomEvent event) {  
        System.out.println("Received event: " + event.getMessage());  
    }  
}

2.1.2 使用@EventListener

在该类中定义一个带有 @EventListener 注解的方法。这个方法将在事件被触发时自动执行。

@Component  
public class MyCustomListener {  
    @EventListener  
    public void handleMyCustomEvent(MyCustomEvent event) {  
        System.out.println("Received event: " + event.getMessage());  
    }  
}

如果希望通过一定的条件对事件进行过滤,可以使用 @EventListener 的 condition 属性。以下实例中只有 event 的 message属性是 my-event 时才会进行调用。

@Component  
public class MyCustomListener {  
    @EventListener(value = {MyCustomEvent.class}, condition = "#event.msg == 'my-event'")
    public void processApplicationEvent(MyCustomEvent event) {
         String message = event.getMessage();
         System.out.println("bean-listener 收到了 publisher 发布的消息: " + message);
    }
}

2.1.3 异步事件监听

前面提到的都是同步处理事件,那如果我们希望某个特定的侦听器异步去处理事件,如何做?

使用 @Async 注解可以实现类内方法的异步调用,这样方法在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。

@EventListener
@Async
public void MyCustomListener(MyCustomEvent event) {
    String message = event.getMessage();
    System.out.println("bean-listener 收到了 publisher 发布的消息: " + message);
}

使用异步监听时,有两点需要注意:

  • 如果异步事件抛出异常,则不会将其传播到调用方。

  • 异步事件监听方法无法通过返回值来发布后续事件,如果需要作为处理结果发布另一个事件,请插入 ApplicationEventPublisher 以手动发布事件。

2.2 发布事件

2.2.1 直接发布

可以使用 ApplicationContextpublishEvent 方法来发布事件。这个方法接受一个 ApplicationEvent 对象作为参数。

@RestController
@RequestMapping("/event")
public class DemoClientController {
    
    @Autowired  
    private ApplicationContext context;  

    @PostMapping("/send")
    public void send() {  
        MyCustomEvent event = new MyCustomEvent(this, "Hello, World!");  
        context.publishEvent(event);  
    }
}

当 send 方法被调用时,会创建一个 MyCustomEvent 对象并发布到 ApplicationContext 中,所有注册监听 MyCustomEvent 的监听器将会接收到该事件并进行处理。

ApplicationContext 在运行期会自动检测到所有实现了 ApplicationListener 的 bean,并将其作为事件接收对象。当我们与 spring 上下文交互触发 publishEvent 方法时,每个实现了 ApplicationListener 的 bean 都会收到 ApplicationEvent 对象,每个 ApplicationListener 可以根据需要只接收自己感兴趣的事件。

2.2.2 自定义发布

要发布上述自定义的 event,需要调用 ApplicationEventPublisher 的 publishEvent 方法,我们可以定义一个实现 ApplicationEventPublisherAware 的类,并注入 IOC来进行调用。

@Component
public class DemoPublisher implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

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

3. 总结

3.1 优点

ApplicationListener 是 Spring 框架中用于事件监听的一个接口,它提供了一种机制,使得开发者可以定义事件和监听器,以便在事件发生时执行相应的处理逻辑。

以下是 ApplicationListener 接口的一些优点:

  1. 解耦:通过事件监听机制,可以将事件的发布者和订阅者分离,降低了组件之间的耦合度,提高了系统的可扩展性和可维护性。
  2. 灵活性:事件监听模型提供了灵活的事件处理方式,可以轻松地实现异步处理、同步处理、事件过滤等功能。
  3. 支持多种事件类型:ApplicationListener 接口支持泛型,可以用于监听不同类型的事件,提高了代码的复用性。
  4. 易于测试和维护:事件监听模型使得代码更加模块化,易于测试和维护。同时,通过观察者模式的应用,可以实现更好的松耦合设计。
  5. 支持事件广播和传播:事件监听机制支持事件广播和传播,可以用于实现系统内的消息传递和通知机制。

@EventListener 是一个 Spring 框架提供的注解,用于实现事件驱动编程。它允许定义事件和事件监听器,当事件被触发时,所有注册监听该事件的监听器将会被调用。

以下是 @EventListener 注解的一些优点:

  1. 解耦:通过事件驱动的方式,可以将业务逻辑与事件处理逻辑分离,降低系统的耦合度。
  2. 可扩展性:当需要添加新的事件处理逻辑时,只需要添加新的监听器即可,无需修改原有代码。
  3. 灵活性:事件驱动的模型使得系统更加灵活,可以轻松地实现跨模块、跨层级的通信和协调。
  4. 支持异步处理:@EventListener 注解支持异步处理,可以大大提高系统的响应速度和吞吐量。
  5. 支持事件过滤:可以通过参数来过滤需要监听的事件类型,减少不必要的处理。
  6. 易于测试和维护:事件驱动的模型使得代码更加模块化,易于测试和维护。

3.2 适用场景

这种机制适用于任何需要组件间通信的场景,例如:

  • 升级系统:当角色升级时,发布一个 LevelUpEvent,订阅者可以响应这个事件来更新UI、播放动画等。
  • 技能系统:当玩家释放技能时,发布一个 SkillUsedEvent,订阅者可以响应这个事件来播放特效、更新冷却时间等。
  • 物品使用:当玩家使用物品时,发布一个 ItemUsedEvent,订阅者可以响应这个事件来更新状态、播放音效等。

点击下载《SpringBoot事件发布及订阅详解含代码示例(值得珍藏)》

你可能感兴趣的:(知识库,spring,boot,后端,java,事件,订阅发布)