Spring事件
📝个人主页:五敷有你
🔥系列专栏:Spring
⛺️稳中求进,晒太阳
Spring事件
简洁
Spring Event(Application Event)就是一个观察者模式,一个bean处理完任务后希望通知其他Bean的行为。
当Spring的事件(Application Event)为Bean和Bean之间的消息同步提供了支持。当一个Bean处理完成一个任务之后,希望另外一个Bean知道并能做相应的处理,这时我们就需要让另外一个Bean监听当前Bean所发生的事件
Spring的事件需要遵循如下流程:
- 自定义事件,继承ApplicationEvent
- 定义事件监听器,实现ApplicationListener
- 使用容器发布事件
演示
自定义事件
@Slf4j public class WebSocketConnectEvent extends ApplicationContextEvent { public WebSocketConnectEvent(ApplicationContext source) { super(source); log.info(" WebSocketConnectEvent 事件产生!!!"); } }
事件监听器
监听器有三种实现方式:实现ApplicationListener接口,使用@EventListener注解,使用@TransactionalEventListener注解。
1.实现ApplicationListener接口
新建一个类实现 ApplicationListener 接口,并且重写 onApplicationEvent 方法注入到Spring容器中,交给Spring管理如下代码新建了一个发送短信监听器,收到事件后执行业务操作
package com.aqiuo.websocket.listen; import com.aqiuo.websocket.WebSocket; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationListener; @Slf4j public class WebSocketConnectListen implements ApplicationListener { @Override public void onApplicationEvent(WebSocketConnectEvent event) { WebSocket webSocket = event.webSocket; log.info(webSocket.toString()); } }
2. 使用@EventListener注解
使用@EventListener标注处理事件的方法,此时Spring创建一个ApplicationListener Bean对象,使用给定的方法处理事件。参数可以指定的事件,这个用到了@AliasFor的能力,放到了@EventListener身上。
注意:一般建议都需要指定此值,不然范围太大了
@Slf4j public class StudentConnectListen { @EventListener(value = {StudentConnectEvent.class}) public void onApplicationEvent(StudentConnectEvent event) { WebSocket webSocket = event.getWebSocket(); System.out.println(webSocket.toString()); } }
3. 使用TransactionEventListener注解
使用@TransactionalEventListener注解来定义一个监听器
@EventListener 和 @TransactionalEventListener 都是 Spring Framework 提供的注解,用于处理应用程序事件。它们的主要区别在于它们处理事件的时间和事务的关联性。
@EventListener:
这个注解可以应用于任何方法,使得该方法成为一个事件监听器。当一个事件被发布时,所有标记为 @EventListener 的方法都会被调用,无论当前是否存在一个活动的事务。这意味着 @EventListener 注解的方法可能在事务提交之前或之后被调用。
@TransactionalEventListener:
这个注解是 @EventListener 的一个特化版本,它允许更精细地控制事件监听器在事务处理过程中的执行时机。@TransactionalEventListener 默认在当前事务提交后才处理事件(TransactionPhase.AFTER_COMMIT),这可以确保事件处理器只在事务成功提交后才被调用。也可以通过 phase 属性来改变事件处理的时机,例如在事务开始前、事务提交前、事务提交后或者事务回滚
注意:此注解需要spring-tx的依赖;
使用实例:
@Component public class DemoListener { @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT,value = { DemoEvent.class }) public void messageListener(DemoEvent event) { String msg = event.getMsg(); System.out.println("DemoListener获取到了监听消息:"+msg); } }
事件发布类
package com.aqiuo.websocket.listen; import com.aqiuo.websocket.WebSocket; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.event.ApplicationContextEvent; import org.springframework.stereotype.Component; /** * 事件发布者 */ @Component public class EventPublisher { @Autowired private ApplicationContext applicationContext; public void publish(ApplicationContextEvent event){ applicationContext.publishEvent(event); } }
配置类
配置类中没有具体的代码逻辑注意作用是为了能扫描到相应的使用注解的类
package com.aqiuo.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(value = "com.aqiuo.websocket.listen") public class EventConfig { }
启动测试
有点问题
出现了applicationContext无法注入的问题。。。