【Spring】ApplicationListener监听器

发布于:2025-09-02 ⋅ 阅读:(15) ⋅ 点赞:(0)

【一】核心作用与功能

ApplicationListener是 Spring 框架中事件驱动模型的核心接口,实现了观察者模式,用于监听和处理 Spring 容器中发布的各种事件。

【1】核心功能:

1.事件监听​:监听 Spring 容器中发布的 ApplicationEvent及其子类事件
2.​事件处理​:定义事件触发时的响应逻辑
3.​解耦通信​:实现组件间的松耦合通信
4.​生命周期监控​:监听 Spring 容器的生命周期事件
5.​自定义事件​:支持开发者扩展自定义业务事件

【2】核心特性:

•​类型安全​:通过泛型指定监听的事件类型
•​异步支持​:可配合 @Async实现异步事件处理
•​顺序控制​:通过 @Order注解控制监听器执行顺序
•​条件过滤​:使用 @Conditional实现条件化监听

在这里插入图片描述

【二】使用案例

【1】案例 1:监听 Spring 内置事件(容器刷新事件)

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

@Component
public class ContextRefreshListener 
    implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        System.out.println("容器刷新完成,开始初始化操作");
        System.out.println("加载的Bean数量: " + 
            event.getApplicationContext().getBeanDefinitionCount());
        
        // 执行初始化逻辑
        initCache();
        preloadData();
    }
    
    private void initCache() {
        // 初始化缓存逻辑
    }
    
    private void preloadData() {
        // 预加载数据逻辑
    }
}

【2】案例 2:自定义业务事件(订单创建事件)

(1)定义自定义事件​

public class OrderCreatedEvent extends ApplicationEvent {
    private final Order order;
    
    public OrderCreatedEvent(Object source, Order order) {
        super(source);
        this.order = order;
    }
    
    public Order getOrder() {
        return order;
    }
}

(2)创建事件监听器​

@Component
public class OrderCreatedListener 
    implements ApplicationListener<OrderCreatedEvent> {

    @Override
    public void onApplicationEvent(OrderCreatedEvent event) {
        Order order = event.getOrder();
        
        // 发送通知
        sendEmailNotification(order);
        
        // 更新库存
        updateInventory(order);
        
        // 记录审计日志
        logAudit(order);
    }
    
    private void sendEmailNotification(Order order) {
        System.out.println("发送订单确认邮件至: " + order.getCustomerEmail());
    }
    
    private void updateInventory(Order order) {
        System.out.println("更新库存,订单ID: " + order.getId());
    }
    
    private void logAudit(Order order) {
        System.out.println("记录审计日志,订单金额: " + order.getAmount());
    }
}

(3)发布事件​

@Service
public class OrderService {
    private final ApplicationEventPublisher eventPublisher;

    public OrderService(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public Order createOrder(OrderRequest request) {
        // 创建订单逻辑
        Order order = new Order(request);
        
        // 发布订单创建事件
        eventPublisher.publishEvent(new OrderCreatedEvent(this, order));
        
        return order;
    }
}

【3】案例 3:使用注解方式实现监听器(推荐)

@Component
public class AnnotationBasedListeners {

    // 监听容器关闭事件
    @EventListener
    public void handleContextClosed(ContextClosedEvent event) {
        System.out.println("容器关闭,执行清理操作");
        releaseResources();
    }

    // 监听自定义订单事件
    @EventListener
    @Async  // 异步处理
    @Order(1) // 执行顺序
    public void handleOrderCreated(OrderCreatedEvent event) {
        System.out.println("异步处理订单创建事件");
        processOrderAsync(event.getOrder());
    }

    // 条件化监听(仅当订单金额大于1000时触发)
    @EventListener(condition = "#event.order.amount > 1000")
    public void handleLargeOrder(OrderCreatedEvent event) {
        System.out.println("处理大额订单: " + event.getOrder().getId());
        notifyManager(event.getOrder());
    }
}

【三】Spring 内置事件类型

在这里插入图片描述

【四】功能拓展

【1】异步事件处理

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize();
        return executor;
    }
}

@Component
public class AsyncEventListener {
    @EventListener
    @Async
    public void handleAsyncEvent(OrderCreatedEvent event) {
        // 耗时操作
        generateReport(event.getOrder());
    }
}

【2】监听器执行顺序控制

@Component
public class OrderedListeners {
    @EventListener
    @Order(1)
    public void firstListener(OrderCreatedEvent event) {
        System.out.println("第一个执行:验证订单");
    }

    @EventListener
    @Order(2)
    public void secondListener(OrderCreatedEvent event) {
        System.out.println("第二个执行:处理支付");
    }

    @EventListener
    @Order(Ordered.LOWEST_PRECEDENCE)
    public void lastListener(OrderCreatedEvent event) {
        System.out.println("最后执行:发送通知");
    }
}

【3】事务绑定事件监听

@Component
public class TransactionalEventListener {
    // 在事务提交后执行
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void afterCommit(OrderCreatedEvent event) {
        System.out.println("事务提交后执行");
    }

    // 在事务回滚后执行
    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
    public void afterRollback(OrderCreatedEvent event) {
        System.out.println("事务回滚后执行");
    }
}

【五】注意事项

1.​事件命名规范​:使用过去时态命名事件(如OrderCreated)
2.​保持监听器无状态​:避免在监听器中维护状态
3.​控制监听器耗时​:长时间操作应使用异步监听
4.​异常处理​:在监听器内部处理异常,避免影响事件发布者
5.​避免循环事件​:防止事件发布导致无限循环
6.​性能监控​:对关键事件监听器进行性能监控

常见问题解决方案

(1)​问题1:监听器未触发​
检查监听器是否被 Spring 管理(添加@Component)
确认事件是否正确发布(使用ApplicationEventPublisher)
检查事件类型是否匹配
(2)​问题2:监听器执行顺序不符合预期​
使用@Order注解明确指定顺序
确保监听器在同一个线程执行(异步监听器顺序不可控)
(3)​问题3:事务事件监听器不触发​
确认方法使用@TransactionalEventListener
检查事务是否成功提交/回滚
确保事件在事务上下文中发布
(4)​问题4:异步监听器阻塞​
配置合适的线程池大小
监控线程池队列长度
避免在监听器中执行长时间阻塞操作


网站公告

今日签到

点亮在社区的每一天
去签到