Spring中事件机制的实现示例
作者:我也有鱼鱼蒸
Spring中的事件机制是基于观察者模式实现的一种组件间通信机制,用于解耦不同组件,实现松耦合的消息传递,下面就来了解一下Spring中事件机制的实现,感兴趣的可以了解一下
Spring中的事件机制是基于观察者模式实现的一种组件间通信机制,用于解耦不同组件,实现松耦合的消息传递,它允许一个组件发送事件,其他组件接收并处理事件,而无需直接依赖彼此。
事件机制的组成
Spring事件机制包含三个核心部分:
- 事件:继承ApplicationEvent的对象,封装需要传递的数据。Spring4.2+可以省略,任意对象都可以作为事件。
- 事件发布者:通过ApplicationEventPublisher接口发布事件,通常由spring管理的bean实现。
- 事件监听器:监听并处理事件的组件,通过@EventListener注解或实现ApplicationListener接口定义。
示例
事件:
首先自定义一个事件类,去实现ApplicationEvent,该父类没有无参构造:
public class MyEvent extends ApplicationEvent { public MyEvent(Object source) { super(source); } }
发布者:
在业务代码内注入ApplicationEventPublisher,通过它去发布事件:
@Autowired private ApplicationEventPublisher applicationEventPublisher; public void enent(){ //业务代码 //发送事件 applicationEventPublisher.publishEvent(new MyEvent(this)); }
监听器:
监听事件类型,两种方式都试一遍:
@Component public class MyLin implements ApplicationListener<MyEvent> { @Override public void onApplicationEvent(MyEvent event) { System.out.println("监听到事件"); } }
@Component public class MyLin2 { //注意方法的参数类型是监听的类型 @EventListener public void onApplicationEvent(MyEvent event) { System.out.println("监听到事件2"); } }
接下来模拟异步的情况:
SimpleApplicationEventMulticaster
SimpleApplicationEventMulticaster是 Spring 框架中事件机制的核心组件,负责将发布的事件多播(multicast) 给所有订阅该事件的监听器,是事件从发布者传递到监听器的 “中介”。
它的主要职责是:
- 接收发布者发布的事件;
- 找到所有监听该事件类型的监听器;
- 将事件分发给这些监听器执行处理逻辑。
特性:
- 事件发布后,它会直接发布在事件的线程中调研监听器的处理方法,发布者需等待所有的监听器完毕后才能继续,可以过setTaskExector(Executor)设置线程池,会将监听器的处理逻辑交到线程池执行,发布者无需等待。
- 支持通过
addApplicationListener(ApplicationListener)
手动注册监听器;
配置好SimpleApplicationEventMulticaster后,通过ApplicationEventPublish发送事件后会提交到配置的线程池中执行。
@Bean public SimpleApplicationEventMulticaster applicationEventMulticaster(ThreadPoolExecutor executor){ SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster(); multicaster.setTaskExecutor(executor); return multicaster; }
异步事件监听器
@Component public class AsyncEventListener { private static final Logger logger = LoggerFactory.getLogger(AsyncEventListener.class); /** * 异步处理事件 - 不会阻塞主线程 */ @Async("taskExecutor") // 指定使用配置的线程池 @EventListener public void handleAsyncEvent(MyEvent event) { logger.info("异步事件处理开始 - 事件: {}", event.getMessage()); logger.info("当前线程: {}", Thread.currentThread().getName()); try { // 模拟耗时操作 Thread.sleep(3000); logger.info("异步事件处理完成: {}", event.getMessage()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); logger.error("异步事件处理被中断", e); } } /** * 同步处理事件 - 会阻塞主线程 */ @EventListener public void handleSyncEvent(MyEvent event) { logger.info("同步事件处理开始 - 事件: {}", event.getMessage()); logger.info("当前线程: {}", Thread.currentThread().getName()); try { // 模拟耗时操作 Thread.sleep(2000); logger.info("同步事件处理完成: {}", event.getMessage()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); logger.error("同步事件处理被中断", e); } } }
@SpringBootTest public class EventTest { @Autowired private BusinessService businessService; @Test public void testAsyncEvent() { System.out.println("测试开始 - 主线程: " + Thread.currentThread().getName()); long startTime = System.currentTimeMillis(); businessService.doBusiness(); long endTime = System.currentTimeMillis(); System.out.println("业务方法执行时间: " + (endTime - startTime) + "ms"); // 给异步事件处理留出时间 try { Thread.sleep(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }
Spring 内置事件
Spring 框架自带一些内置事件,用于通知容器生命周期的关键节点,常见的有:
事件类型 | 触发时机 |
---|---|
ContextRefreshedEvent | Spring 容器初始化完成(所有 Bean 加载完成) |
ContextStartedEvent | 容器启动时(调用start()方法) |
ContextStoppedEvent | 容器停止时(调用stop()方法) |
ContextClosedEvent | 容器关闭时(调用close()方法) |
ApplicationFailedEvent | 应用启动失败时(Spring Boot 中常用) |
到此这篇关于Spring中事件机制的实现示例的文章就介绍到这了,更多相关Spring 事件机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!