Spring 的本地消息

18 阅读3分钟

观察者模式、事件通知机制和 Spring 的本地消息机制三者之间存在明确的实现关系,具体来说:

1. 观察者模式与事件通知机制的关系

  • 观察者模式是事件通知机制的具体实现方式之一
  • 事件驱动编程是一种架构范式,而观察者模式是实现这种范式的具体设计手段
  • 事件通知机制通常采用"发布-订阅"模式,这正是观察者模式的典型应用场景

2. Spring 事件机制确实使用了观察者模式

Spring 框架的事件驱动机制(ApplicationEvent)是观察者模式的标准实现

Spring 组件观察者模式角色说明
ApplicationContext事件源(Subject)触发事件的主体,继承自 ApplicationEventPublisher
ApplicationEvent事件(事件对象)继承自 JDK 的 EventObject,携带事件数据
ApplicationListener观察者(Observer)监听特定事件,事件发生时 onApplicationEvent() 方法被回调
ApplicationEventMulticaster事件广播器负责注册监听器和广播事件,解耦发布者和订阅者

3. "Spring 本地消息"的理解

您提到的"Spring 本地消息"通常指的是Spring 事件机制(进程内事件通知),与跨进程的 MQ 消息队列不同:

  • 同一 JVM 进程内的组件解耦通信
  • 通过 ApplicationEventPublisher.publishEvent() 发布事件
  • 监听器通过 @EventListener 注解或实现 ApplicationListener 接口来接收通知

典型应用场景

例如用户注册成功后,需要同时发送短信、邮件和优惠券:

// 发布事件
@Component
public class UserService {
    @Autowired private ApplicationEventPublisher publisher;
    
    public void register(String username) {
        // 保存用户...
        publisher.publishEvent(new UserRegisterEvent(this, username));
    }
}

// 监听事件(多个观察者)
@Component
public class EmailListener {
    @EventListener
    public void sendEmail(UserRegisterEvent event) { /* ... */ }
}

@Component
public class SmsListener {
    @EventListener
    public void sendSms(UserRegisterEvent event) { /* ... */ }
}

总结:事件通知机制通常基于观察者模式实现,而 Spring 的事件机制(即您说的"本地消息")正是这一模式的典型应用,提供了进程内组件间松耦合通信的能力。

以下是 Spring 事件机制中各组件协作关系的流程图,完整展示了从事件发布到处理的全生命周期:

┌─────────────────────────────────────────────────────────────────────────┐
│                       Spring 容器初始化阶段                                │
└─────────────────────────────────────────────────────────────────────────┘
                                   │
                                   ▼
┌─────────────────────────────────────────────────────────────────────────┐
│  1. 扫描并发现所有 ApplicationListener 实现类(如 EmailListener)          │
│  2. 将监听器注册到 ApplicationEventMulticaster 的注册表                  │
│     (内部维护 Map<Class<?>, List<ApplicationListener>> 映射关系)       │
└─────────────────────────────────────────────────────────────────────────┘
                                   │
                                   ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                        运行时事件发布处理流程                              │
└─────────────────────────────────────────────────────────────────────────┘
                                   │
                                   │
     ┌─────────────────────────────┼──────────────────────────────────┐
     │  用户注册业务逻辑完成           │                                  │
     │                               ▼                                  │
     │              ┌──────────────────────────────────┐                │
     │              │ ApplicationContext (ConcreteSubject)│            │
     │              │   - 事件发布入口                     │            │
     │              └──────────────────────────────────┘                │
     │                               │ publishEvent()                    │
     │                               ▼                                  │
     │              ┌──────────────────────────────────┐                │
     │              │  UserRegisterEvent (ConcreteEvent)  │            │
     │              │   - 封装事件数据(用户、时间戳等)        │            │
     │              │   - extends ApplicationEvent        │            │
     │              └──────────────────────────────────┘                │
     │                               │                                  │
     │                               ▼                                  │
     └─────────────────────────────>│                                  │
                                    │                                  │
     ┌─────────────────────────────────────────────────────────────┐    │
     │         ApplicationEventMulticaster (事件广播器)               │    │
     │         - 管理所有监听器注册表                                   │    │
     │         - 匹配事件类型与监听器                                   │    │
     │                                                               │    │
     │  ┌──────────────────────────────────────────────────────────┐ │    │
     │  │  1. 接收事件                                              │ │    │
     │  │  2. 根据事件类型 UserRegisterEvent 查找匹配的监听器列表   │ │    │
     │  │  3. 遍历调用监听器回调方法                                │ │    │
     │  └──────────────────────────────────────────────────────────┘ │    │
     └─────────────────────────────────────────────────────────────┘    │
                                   │                                  │
              ┌───────────────────┼───────────────────┐              │
              │                   │                   │              │
              ▼                   ▼                   ▼              │
     ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐     │
     │ EmailListener   │ │ CouponListener  │ │ SmsListener     │     │
     │  (观察者1)        │ │  (观察者2)        │ │  (观察者3)        │     │
     │                 │ │                 │ │                 │     │
     │onApplicationEvent│ │onApplicationEvent│ │onApplicationEvent│     │
     │                 │ │                 │ │                 │     │
     └─────────────────┘ └─────────────────┘ └─────────────────┘     │
              │                   │                   │              │
              │                   │                   │              │
              ▼                   ▼                   ▼              │
     ┌─────────────────────────────────────────────────────────────┐    │
     │              业务处理(发送邮件、发放优惠券、发送短信)           │    │
     └─────────────────────────────────────────────────────────────┘    │
                                                                       │
     ┌─────────────────────────────────────────────────────────────┐    │
     │              @Async 可选:异步线程池执行监听器逻辑                │    │
     └─────────────────────────────────────────────────────────────┘    │

关键协作关系说明

1. ApplicationContext (ConcreteSubject)

  • 职责:作为事件发布入口,持有 ApplicationEventPublisher 接口
  • 核心方法publishEvent(event)
  • 位置:继承自 ApplicationEventPublisher 接口,实际调用委托给 Multicaster

2. UserRegisterEvent (ConcreteEvent)

  • 职责:封装具体业务数据,继承自 ApplicationEvent
  • 关键属性source(事件源对象)、timestamp(发布时间)
  • 作用:作为载体在组件间传递信息

3. ApplicationEventMulticaster (事件广播器核心)

  • 本质:观察者模式中的 "调度中心"
  • 核心功能
    • 注册addApplicationListener() 管理所有监听器列表
    • 匹配:根据事件类型动态筛选匹配的 ApplicationListener
    • 广播multicastEvent() 遍历调用监听器回调
  • 实现类:默认使用 SimpleApplicationEventMulticaster,支持同步/异步广播

4. ApplicationListener (Observer)

  • 职责:事件处理逻辑载体
  • 两种实现方式
    • 接口实现:实现 ApplicationListener<UserRegisterEvent> 接口
    • 注解方式:使用 @EventListener 注解方法(推荐)
  • 扩展能力:支持 @Order 控制执行顺序、@Async 异步执行

时序流程(简化版)

sequenceDiagram
    participant UserService as 用户服务
    participant Context as ApplicationContext
    participant Event as UserRegisterEvent
    participant Multicaster as ApplicationEventMulticaster
    participant Listeners as ApplicationListener列表

    UserService->>Context: registerUser()
    Context->>Event: 创建事件对象
    Context->>Multicaster: publishEvent(event)
    Multicaster->>Listeners: multicastEvent(event)
    loop 对每个匹配的监听器
        Multicaster->>Listeners: onApplicationEvent(event)
        Listeners-->>Listeners: 处理业务逻辑
    end
    Listeners-->>Multicaster: 返回
    Multicaster-->>Context: 返回
    Context-->>UserService: 完成

总结ApplicationEventMulticaster 作为核心调度器,在发布者和订阅者之间实现了解耦,是整个观察者模式能够灵活运作的中枢神经。