当前位置: 首页 > news >正文

ApplicationContext 事件发布与监听机制详解

ApplicationContext 事件发布与监听机制详解

ApplicationContext 接口是 Spring 框架的核心容器接口,它提供了事件发布与监听机制,允许应用程序组件之间通过事件进行松耦合通信。这种机制基于观察者模式,实现了发布-订阅模型。

核心概念

  1. 事件(ApplicationEvent): 所有事件类的基类,Spring 提供了多种内置事件
  2. 事件发布者(ApplicationEventPublisher): 发布事件的接口,ApplicationContext 实现了此接口
  3. 事件监听器(ApplicationListener): 监听特定事件的接口

主要方法

1. 事件发布相关方法

  • publishEvent(Object event): 发布事件(在 Spring 4.2+ 中,可以直接发布任何对象作为事件)
  • publishEvent(ApplicationEvent event): 发布标准 ApplicationEvent 事件

2. 事件监听相关方法

  • 通过实现 ApplicationListener<E extends ApplicationEvent> 接口
  • 或使用 @EventListener 注解(Spring 4.2+ 推荐方式)

内置事件类型

Spring 提供了一些内置事件:

  1. ContextRefreshedEvent: ApplicationContext 初始化或刷新时触发
  2. ContextStartedEvent: ApplicationContext 启动时触发
  3. ContextStoppedEvent: ApplicationContext 停止时触发
  4. ContextClosedEvent: ApplicationContext 关闭时触发
  5. RequestHandledEvent: Web 请求处理完成时触发(仅适用于 Web 应用)

实现方式

方式1:实现 ApplicationListener 接口

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;@Component
public class MyContextRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {System.out.println("Context refreshed event received!");}
}

方式2:使用 @EventListener 注解(推荐)

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@Component
public class MyEventListener {@EventListenerpublic void handleContextRefresh(ContextRefreshedEvent event) {System.out.println("Context refreshed event handled via @EventListener!");}// 可以监听多个事件类型@EventListener({ContextStartedEvent.class, ContextStoppedEvent.class})public void handleMultipleEvents(ApplicationEvent event) {if (event instanceof ContextStartedEvent) {System.out.println("Context started event received");} else if (event instanceof ContextStoppedEvent) {System.out.println("Context stopped event received");}}
}

方式3:自定义事件

  1. 定义自定义事件类:
import org.springframework.context.ApplicationEvent;public class CustomEvent extends ApplicationEvent {private String message;public CustomEvent(Object source, String message) {super(source);this.message = message;}public String getMessage() {return message;}
}
  1. 创建事件发布者:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;@Service
public class EventPublisherService {@Autowiredprivate ApplicationEventPublisher eventPublisher;public void publishCustomEvent(String message) {System.out.println("Publishing custom event...");CustomEvent event = new CustomEvent(this, message);eventPublisher.publishEvent(event);}
}
  1. 创建事件监听器:
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@Component
public class CustomEventListener {@EventListenerpublic void handleCustomEvent(CustomEvent event) {System.out.println("Received custom event - Message: " + event.getMessage());}
}

完整示例

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@SpringBootApplication
public class EventApplication {public static void main(String[] args) {SpringApplication.run(EventApplication.class, args);}
}// 自定义事件
class OrderCreatedEvent {private final String orderId;public OrderCreatedEvent(String orderId) {this.orderId = orderId;}public String getOrderId() {return orderId;}
}// 事件发布服务
@Component
class OrderService {private final ApplicationEventPublisher eventPublisher;public OrderService(ApplicationEventPublisher eventPublisher) {this.eventPublisher = eventPublisher;}public void createOrder(String orderId) {System.out.println("Creating order: " + orderId);// 业务逻辑...eventPublisher.publishEvent(new OrderCreatedEvent(orderId));}
}// 方式1:实现 ApplicationListener 接口
@Component
class OrderNotificationListener implements ApplicationListener<OrderCreatedEvent> {@Overridepublic void onApplicationEvent(OrderCreatedEvent event) {System.out.println("Sending notification for order: " + event.getOrderId());}
}// 方式2:使用 @EventListener 注解
@Component
class OrderInventoryListener {@EventListenerpublic void updateInventory(OrderCreatedEvent event) {System.out.println("Updating inventory for order: " + event.getOrderId());}
}// 监听内置事件
@Component
class ContextStartupListener {@EventListenerpublic void onContextRefreshed(ContextRefreshedEvent event) {System.out.println("Application context has been refreshed!");}
}

异步事件处理

要使事件监听异步执行,可以添加 @Async 注解:

  1. 首先在配置类上启用异步支持:
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;@Configuration
@EnableAsync
public class AsyncConfig {
}
  1. 然后在监听方法上添加 @Async
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;@Component
public class AsyncEventListener {@Async@EventListenerpublic void handleAsyncEvent(OrderCreatedEvent event) {System.out.println("Processing event asynchronously for order: " + event.getOrderId());try {Thread.sleep(2000); // 模拟耗时操作} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println("Async processing completed for order: " + event.getOrderId());}
}

事件传播顺序

如果需要控制多个监听器的执行顺序,可以使用 @Order 注解:

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;@Component
@Order(1)
class FirstOrderListener {@EventListenerpublic void handleFirst(OrderCreatedEvent event) {System.out.println("First listener for order: " + event.getOrderId());}
}@Component
@Order(2)
class SecondOrderListener {@EventListenerpublic void handleSecond(OrderCreatedEvent event) {System.out.println("Second listener for order: " + event.getOrderId());}
}

总结

ApplicationContext 的事件机制提供了强大的组件间解耦通信能力:

  1. 松耦合:发布者和监听者不需要知道彼此的存在
  2. 灵活性:可以轻松添加或移除监听器而不影响现有代码
  3. 可扩展性:支持自定义事件类型
  4. 异步支持:通过 @Async 实现非阻塞事件处理
  5. 顺序控制:通过 @Order 控制监听器执行顺序

这种机制特别适用于实现跨模块的通知、日志记录、审计跟踪、缓存失效等场景。

http://www.dtcms.com/a/286050.html

相关文章:

  • 反射机制的登录系统
  • PHP 8.0 升级到 PHP 8.1
  • 创建型模式
  • 基于 HT 的 3D 可视化智慧矿山开发实现
  • 从一开始的网络攻防(四):XSS
  • hadoop(服务器伪分布式搭建)
  • FastAdmin后台登录地址变更原理与手动修改方法-后台入口机制原理解析-优雅草卓伊凡
  • Hadoop安全机制深度剖析:Kerberos认证与HDFS ACL细粒度权限控制
  • 《Web安全之深度学习实战》读书笔记总结
  • AI赋能轮胎安全:基于YOLO11的智能裂纹检测系统
  • 基于springboot+vue+mysql的智慧社区设计与实现(源码+论文+开题报告)
  • Docker Swarm 集群使用记录
  • Matlab打开慢、加载慢的解决办法
  • 免费的一些工具收集
  • 【Oracle】centos7离线静默安装oracle11g(p13390677_112040)
  • Hive 向量化执行引擎 Vectorized Execution 常见 NPE 报错分析及解决
  • 全球天气预报5天(经纬度版)免费API接口教程
  • Python绘制数据(二)
  • JAVA面试宝典 -《微服务治理:从链路追踪到熔断》
  • 某邮生活旋转验证码识别
  • 算法竞赛备赛——【图论】求最短路径——小结
  • 前端之CSS
  • MyBatis之关联查询
  • WEB安全架构
  • Tomcat及Nginx部署使用
  • DevExpress WinForms v25.1 亮点:AI驱动的语义搜索、模板库更新
  • RPC 与 Feign 的区别笔记
  • SQLite 数据库字段类型-详细说明,数据类型详细说明。
  • 服务器mysql数据的简单备份脚本
  • 深入浅出MyBatis缓存:如何让数据库交互飞起来