昔年浅巷

昔年浅巷

SpringBoot 初探发布订阅模式

13
2024-10-19

接入指南

SpringBoot的发布订阅模式接入十分简单,只需要实现事件类【继承ApplicationEvent】和监听类【@TransactionalEventListener】即可。

1697447656380.webp

事件触发类

package org.xnqx.qbittorrentmanagerservice.event;

import lombok.Getter;
import org.xnqx.qbittorrentspringbootstart.entity.TorrentBriefInfo;
import org.springframework.context.ApplicationEvent;

import java.util.List;

/**
 * @program: common-base
 * @description: 种子下载事件
 * @author: Luke
 * @create: 2023/10/16
 **/
@Getter
public class TorrentDownloadEvent extends ApplicationEvent {

    private final List<TorrentBriefInfo> torrentBriefInfos;

    public TorrentDownloadEvent(Object source, List<TorrentBriefInfo> torrentBriefInfos) {
        super(source);
        this.torrentBriefInfos = torrentBriefInfos;
    }
}

事件监听处理类

package org.xnqx.qbittorrentmanagerservice.event.listener;

import lombok.extern.slf4j.Slf4j;
import org.xnqx.qbittorrentmanagerservice.event.TorrentDownloadEvent;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

/**
 * @program: common-base
 * @description: 种子下载事件监听器
 * @author: Luke
 * @create: 2023/10/16
 **/
@Slf4j
@Component
public class TorrentDownloadListener {

    @Async
    @TransactionalEventListener(classes = TorrentDownloadEvent.class, fallbackExecution = true)
    public void torrentDownOne(TorrentDownloadEvent event) {
        log.info("进入种子下载消费第一阶段!!!!!!!!");
    }

    @Async
    @TransactionalEventListener(classes = TorrentDownloadEvent.class, fallbackExecution = true)
    public void torrentDownTwo(TorrentDownloadEvent event) {
        log.info("进入种子下载消费第二阶段!!!!!!!!");
    }
}

事件埋点/触发

	@Autowired
	ApplicationEventPublisher applicationEventPublisher;

    @Test
    void testMsgPush() {
        applicationEventPublisher.publishEvent(new TorrentDownloadEvent(this, Lists.newArrayList()));
    }

事件驱动编程

  1. 事件监听机制可以理解为是一种观察者模式【观察者模式的定义:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。】,有数据发布者(事件源)和数据接受者(监听器);

1697448023961.webp

Spring/Spring Boot在面向事件驱动编程方面提供了以下内容:

  • 事件(Events):Spring提供了一个基于观察者模式的事件模型。通过定义和发布事件,可以将不同组件之间解耦,使其能够以异步方式进行通信。
  • 事件监听器(Event Listeners):通过实现ApplicationListener接口或使用@EventListener注解,可以创建事件监听器。这些监听器用于接收和处理发布的事件,并根据需要执行相应的操作。
  • 事件发布器(Event Publisher):Spring框架提供了ApplicationEventPublisher接口,用于发布事件。可以通过调用publishEvent()方法来发布自定义的事件,从而通知所有注册的监听器。
  • 领域事件(Domain Events):在面向领域驱动设计(Domain-Driven Design)的应用程序中,领域事件用于表示系统中重要的业务操作或状态变化。Spring框架提供了支持,允许开发人员将领域事件与应用程序的其他部分集成起来。
  • 异步事件处理(Asynchronous Event Handling):Spring支持将事件处理设置为异步执行。可以使用@Async注解将事件处理方法标记为异步方法,从而使事件的处理在独立的线程中执行。
  • 条件事件(Conditional Events):使用@Conditional注解,可以根据满足特定条件才触发事件。这样可以根据应用程序的状态或配置选择性地发布事件,从而更加灵活地控制事件的触发。
  • @TransactionalEventListener:@TransactionalEventListener实现监听事件时的事务隔离。

总结

使用发布-订阅模式有以下几个好处:

  1. 解耦:使用发布-订阅模式可以将事件发布者和事件订阅者解耦。发布者无需知道谁订阅了事件,订阅者也无需知道事件是由谁发布的。
  2. 扩展性:使用发布-订阅模式可以更轻松地扩展应用程序,因为它允许在不修改现有代码的情况下添加新的事件和事件处理器。
  3. 异步处理:使用发布-订阅模式可以异步地处理事件,这样可以提高应用程序的性能和响应性。
  4. 灵活性:使用Spring的事件机制,可以根据需要选择同步或异步方式处理事件。可以使用@EventListener注解来简化事件处理器的编写。
  5. 易于测试:使用发布-订阅模式可以更容易地测试应用程序,因为可以模拟事件并验证事件处理器的行为。

总之,使用Spring的发布-订阅模式可以让应用程序更加灵活、可扩展、可维护和易于测试。它是实现事件驱动的应用程序的一种优秀的方法。

PS:给自己立个flag,后面阅读相关源码, 了解SpringBoot实现发布订阅模式的原理。