Spring 的本地消息

观察者模式、事件通知机制和 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 接口来接收通知

典型应用场景

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

java 复制代码
// 发布事件
@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 事件机制中各组件协作关系的流程图,完整展示了从事件发布到处理的全生命周期:

scss 复制代码
┌─────────────────────────────────────────────────────────────────────────┐
│                       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 作为核心调度器 ,在发布者和订阅者之间实现了解耦,是整个观察者模式能够灵活运作的中枢神经。

相关推荐
pengzhuofan2 小时前
Java开发中的AI Prompt管理指南
java·开发语言·prompt
wh_cxy2 小时前
Java泛型通配符入门教程
java
乌暮3 小时前
JavaEE初阶--线程的状态
java·java-ee
悟空码字3 小时前
SpringBoot 整合 RabbitMQ:和这只“兔子”交朋友
java·后端·rabbitmq
雨中飘荡的记忆3 小时前
Java并发工具深度剖析与实战
java
小股虫3 小时前
从零开始:ActiveMQ安装、Java应用实战与Web控制台体验
java·activemq·java-activemq
java_logo3 小时前
RUSTFS Docker 容器化部署指南
java·运维·docker·容器·jenkins·运维开发
uup3 小时前
秒杀系统中的超卖与重复下单问题
java
用户8307196840823 小时前
Spring注入原型Bean,为啥”新“对象“不翼而飞”?
java