spring|spring event|Spring内置事件驱动编程模型
事件驱动编程模型
基于经典的观察者模式实现,当一个组件(发布者)发生了某件重要的事(如用户注册),它只需“广播”一个事件,而无需关心谁会处理。其他对此感兴趣的组件(监听器)可以“订阅”并响应这个事件,彼此互不直接依赖
核心角色
- 事件(Event)
信息的载体,封装了需要传递的数据。在Spring 4.2之后,它可以是任何普通的Java对象(POJO),不再强制继承ApplicationEvent类
- 事件发布者(Publisher)
负责发布事件的组件。通过注入 ApplicationEventPublisher 接口并调用其 publishEvent 方法来实现
- 事件监听器(Listener)
负责监听并处理特定事件的组件。通过实现 ApplicationListener 接口或使用 @EventListener 注解来定义
源码
https://gitee.com/jysemel-spring/spring-boot/tree/master/action/action-event
源码流程
- 发布
业务逻辑触发时通过 ApplicationEventPublisher 发布一个事件对象
- 广播
ApplicationContext 作为“广播器”,会将接收到的事件分发给所有注册的、对该事件类型感兴趣的监听器
- 处理
监听器接收到事件后,执行其定义好的业务逻辑
demo 源码
- 定义事件类型
package com.jysemel.spring.boot.study.event;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;
@Setter
@Getter
public class UserRegisteredEvent extends ApplicationEvent {
private String userName;
private String nickName;
public UserRegisteredEvent(Object source, String userName, String nickName) {
super(source);
this.userName = userName;
this.nickName = nickName;
}
}
事件发布
package com.jysemel.spring.boot.study.service;
import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
@Service
public class StoreService {
@Autowired
private ApplicationEventPublisher publisher;
public void register(UserRegisteredEvent registeredEvent) {
// 执行核心注册逻辑...
System.out.println("用户 " + registeredEvent.getNickName() + " 注册成功");
// 发布事件
publisher.publishEvent(registeredEvent);
}
}
事件监听
package com.jysemel.spring.boot.study.listener;
import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
* 方式二:使用@EventListener注解(更推荐)
*/
@Component
public class CouponListener {
@EventListener
public void handleUserRegisteredEvent(UserRegisteredEvent event) {
System.out.println("方式二:使用@EventListener注解 ");
System.out.println("赠送新人优惠券给用户:" + event.getNickName());
}
}
演示结果
http://127.0.0.1:8083/api/user/reg?userName=113.9526&nickName=22.5431

用户 22.5431 注册成功
发送欢迎邮件给用户:22.5431
方式二:使用@EventListener注解
赠送新人优惠券给用户:22.5431
