本文目录导读:

我将为您全面介绍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,可以有效提升代码的维护性和扩展性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播