本文目录导读:

我将为您全面介绍Spring Event的实战案例,从基础到进阶,包含完整的代码示例。
Spring Event基础概念
1 核心组件
- 事件(Event):继承ApplicationEvent的对象
- 监听器(Listener):处理事件的对象
- 发布器(Publisher):发布事件的对象
- 事件广播器(Multicaster):Spring内部用于管理监听器的组件
实战案例:用户注册系统
1 项目结构
com.example.eventdemo
├── event
│ ├── UserRegisterEvent.java
│ └── OrderEvent.java
├── listener
│ ├── EmailListener.java
│ ├── SmsListener.java
│ ├── CouponListener.java
│ └── LogListener.java
├── service
│ ├── UserService.java
│ └── OrderService.java
└── controller
└── DemoController.java
2 事件定义
// 用户注册事件
public class UserRegisterEvent extends ApplicationEvent {
private final String username;
private final String email;
private final String phone;
private final Date registerTime;
public UserRegisterEvent(Object source, String username, String email, String phone) {
super(source);
this.username = username;
this.email = email;
this.phone = phone;
this.registerTime = new Date();
}
// getter/setter 方法
public String getUsername() { return username; }
public String getEmail() { return email; }
public String getPhone() { return phone; }
public Date getRegisterTime() { return registerTime; }
}
// 订单创建事件
public class OrderEvent extends ApplicationEvent {
private final Long orderId;
private final BigDecimal amount;
private final Long userId;
public OrderEvent(Object source, Long orderId, BigDecimal amount, Long userId) {
super(source);
this.orderId = orderId;
this.amount = amount;
this.userId = userId;
}
// getter/setter 方法
public Long getOrderId() { return orderId; }
public BigDecimal getAmount() { return amount; }
public Long getUserId() { return userId; }
}
3 服务层实现
@Service
@Slf4j
public class UserService {
@Autowired
private ApplicationEventPublisher eventPublisher;
/**
* 用户注册
*/
@Transactional
public void registerUser(String username, String email, String phone) {
// 1. 保存用户信息到数据库
log.info("保存用户信息: {}, {}, {}", username, email, phone);
// 2. 发布用户注册事件
UserRegisterEvent event = new UserRegisterEvent(this, username, email, phone);
eventPublisher.publishEvent(event);
log.info("用户注册完成,事件已发布");
}
}
@Service
@Slf4j
public class OrderService {
@Autowired
private ApplicationEventPublisher eventPublisher;
/**
* 创建订单
*/
@Transactional
public void createOrder(Long userId, BigDecimal amount) {
// 1. 创建订单
Long orderId = System.currentTimeMillis();
log.info("创建订单: orderId={}, userId={}, amount={}", orderId, userId, amount);
// 2. 发布订单事件
OrderEvent event = new OrderEvent(this, orderId, amount, userId);
eventPublisher.publishEvent(event);
log.info("订单创建完成,事件已发布");
}
}
4 监听器实现
// 邮件监听器 - 同步处理
@Component
@Slf4j
public class EmailListener {
@EventListener
@Async("taskExecutor")
public void handleUserRegisterEvent(UserRegisterEvent event) {
log.info("发送欢迎邮件给用户: {}", event.getUsername());
// 模拟邮件发送
try {
Thread.sleep(1000);
log.info("邮件发送成功: {} -> {}", event.getEmail(), event.getUsername());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("邮件发送失败", e);
}
}
}
// 短信监听器
@Component
@Slf4j
public class SmsListener {
@EventListener
@Async("taskExecutor")
public void handleUserRegisterEvent(UserRegisterEvent event) {
log.info("发送注册成功短信: {}", event.getPhone());
// 模拟短信发送
try {
Thread.sleep(500);
log.info("短信发送成功: {} -> {}", event.getPhone(), event.getUsername());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("短信发送失败", e);
}
}
}
// 优惠券监听器
@Component
@Slf4j
public class CouponListener {
@EventListener
@Async("taskExecutor")
public void handleUserRegisterEvent(UserRegisterEvent event) {
log.info("发送新人优惠券给用户: {}", event.getUsername());
// 模拟优惠券发放
log.info("优惠券发放成功: 用户{}获得100元新人礼包", event.getUsername());
}
@EventListener
@Async("taskExecutor")
public void handleOrderEvent(OrderEvent event) {
if (event.getAmount().compareTo(new BigDecimal("1000")) > 0) {
log.info("订单金额超过1000元,发放VIP优惠券: orderId={}", event.getOrderId());
}
}
}
// 日志监听器 - 同步处理
@Component
@Slf4j
public class LogListener {
@EventListener
public void handleUserRegisterEvent(UserRegisterEvent event) {
log.info("记录用户注册日志: {}", event.getUsername());
}
@EventListener
@Order(1) // 设置执行顺序
public void handleOrderEvent(OrderEvent event) {
log.info("记录订单创建日志: orderId={}", event.getOrderId());
}
}
5 异步配置
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
@Bean("taskExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("event-thread-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (throwable, method, objects) -> {
log.error("异步事件处理异常: {}, 方法: {}", throwable.getMessage(), method.getName());
};
}
}
高级特性案例
1 条件事件监听
@Component
@Slf4j
public class ConditionalListener {
/**
* 只有特定条件下才处理事件
*/
@EventListener
@ConditionalOnProperty(name = "app.notification.email.enabled", havingValue = "true")
public void conditionalHandle(UserRegisterEvent event) {
log.info("邮件通知已启用,发送邮件给: {}", event.getEmail());
}
}
2 指定监听器ID
@Component
@Slf4j
public class CustomizedListener {
@EventListener
public void handleEvent(UserRegisterEvent event) {
// 通过 @Order 控制顺序
}
// 使用泛型事件
@EventListener
public void handleGenericEvent(MyEntityEvent<Order> event) {
Order order = event.getData();
log.info("处理订单泛型事件: {}", order);
}
}
// 泛型事件类
public class MyEntityEvent<T> extends ApplicationEvent {
private final T data;
public MyEntityEvent(Object source, T data) {
super(source);
this.data = data;
}
public T getData() { return data; }
}
3 事务事件监听
@Component
@Slf4j
public class TransactionalListener {
/**
* 事务提交后处理
* @TransactionalEventListener 默认为 AFTER_COMMIT
*/
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleAfterCommit(UserRegisterEvent event) {
log.info("事务提交后发送邮件: {}", event.getUsername());
}
@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void handleAfterRollback(UserRegisterEvent event) {
log.info("事务回滚后记录日志: {}", event.getUsername());
}
@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
public void handleBeforeCommit(UserRegisterEvent event) {
log.info("事务提交前处理: {}", event.getUsername());
}
}
4 事件异常处理
@Configuration
@Slf4j
public class EventExceptionConfig {
@Bean
public ApplicationListener<ApplicationEvent> eventListener() {
return event -> {
try {
// 自定义事件处理逻辑
handleEvent(event);
} catch (Exception e) {
log.error("事件处理异常: {}", event.getClass().getSimpleName(), e);
}
};
}
/**
* 事件监听器工厂,可以添加自定义的后处理器
*/
@Bean
public EventListenerFactory eventListenerFactory(ApplicationContext context) {
DefaultEventListenerFactory factory = new DefaultEventListenerFactory();
factory.setOrder(Ordered.LOWEST_PRECEDENCE);
return factory;
}
}
测试案例
@SpringBootTest
@Slf4j
public class EventTest {
@Autowired
private UserService userService;
@Autowired
private OrderService orderService;
@Test
public void testUserRegisterEvent() throws InterruptedException {
log.info("开始测试用户注册事件");
userService.registerUser("张三", "zhangsan@example.com", "13800138000");
// 等待异步事件处理完成
Thread.sleep(3000);
log.info("用户注册事件测试完成");
}
@Test
public void testOrderEvent() throws InterruptedException {
log.info("开始测试订单事件");
orderService.createOrder(1L, new BigDecimal("1500.00"));
Thread.sleep(2000);
log.info("订单事件测试完成");
}
}
Controller示例
@RestController
@RequestMapping("/api/demo")
@Slf4j
public class DemoController {
@Autowired
private UserService userService;
@Autowired
private OrderService orderService;
@PostMapping("/register")
public Result register(@RequestBody RegisterRequest request) {
userService.registerUser(request.getUsername(), request.getEmail(), request.getPhone());
return Result.success("注册成功");
}
@PostMapping("/order")
public Result createOrder(@RequestBody OrderRequest request) {
orderService.createOrder(request.getUserId(), request.getAmount());
return Result.success("下单成功");
}
}
生产环境配置建议
# application.yml
spring:
task:
execution:
pool:
core-size: 8
max-size: 16
queue-capacity: 200
keep-alive: 60s
thread-name-prefix: event-executor-
application:
name: event-demo
logging:
level:
com.example.eventdemo: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
最佳实践
1 事件命名规范
// 使用过去时态命名事件 UserRegisteredEvent // 推荐 UserRegisterEvent // 可以接受 RegisterUserEvent // 不推荐
2 监听器设计原则
@Component
@Slf4j
public class RecommendedListener {
/**
* 1. 监听器应该保持轻量级
* 2. 异常应该被捕获,不影响其他监听器
* 3. 考虑使用 @Async 处理耗时操作
*/
@EventListener
@Async("taskExecutor")
public void handleEvent(UserRegisterEvent event) {
try {
log.info("处理事件: {}", event.getUsername());
// 业务处理
} catch (Exception e) {
log.error("事件处理失败", e);
}
}
}
3 监控和性能
@Component
@Aspect
@Slf4j
public class EventMonitor {
@Around("@annotation(org.springframework.context.event.EventListener)")
public Object monitorEvent(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - start;
log.info("事件处理耗时: {} ms", duration);
return result;
} catch (Exception e) {
log.error("事件处理异常: {}", e.getMessage(), e);
throw e;
}
}
}
Spring Event提供了:
- 解耦:业务组件之间松耦合
- 异步处理:提高系统响应速度
- 顺序控制:@Order注解控制监听器执行顺序
- 事务集成:@TransactionalEventListener支持事务边界
- 泛型支持:支持泛型事件类型
通过合理使用Spring Event,可以有效提升代码的维护性和扩展性。