文章目录
介绍
Spring提供了完整的事件发布与监听模型,在该模型中,事件发布方只需将事件发布出去,无需关心有多少个对应的事件监听器;
监听器无需关心是谁发布了事件,并且可以同时监听来自多个事件发布方发布的事件,优点是解耦,帮助大家更好地使用发布/订阅模式;
步骤
完成事件监听,发布者应该注入一个 ApplicationEventPublisher
对象;
监听器应实现 ApplicationListener
接口或者使用注解代替;
如果想要事件监听异步化的话,启动类上还需要添加 @EnableAsync
注解;
例子
ApplicationEventPublisher 事件发布
/**
* @author 岳晓鵬
* @version 1.0
* @date 2022/6/16 17:57
* @description
*/
public class ApplicationEventTest {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
/**
* 定义事件发布者
*/
public void publish(){
PushVo pushVo = PushVo.builder().build();
applicationEventPublisher.publishEvent(pushVo);
}
}
ApplicationListener 事件监听
因为在场景中,需要异步监听,所以在这里添加了@Async
注解,
@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void xyPush(PushVo push) {
log.info("监听:{}", push);
// 省略代码
}
@EventListener与@TransactionalEventListener注解
上面说过,监听器应实现 ApplicationListener
接口,但其实使用这两个其中一个注解就可以;
使用@EventListener
修饰的监听器,有个弊端,就是不一定可以查到之前插入数据库的数据(因为上一个事务还没有提交);
所以就引出了@TransactionalEventListener
注解,能够实现在控制事务的同时,完成对对事件的处理,具体可以看下注解详细参数:
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EventListener
public @interface TransactionalEventListener {
/**
* TransactionPhase
*/
TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;
/**
*
*/
boolean fallbackExecution() default false;
/**
*
*/
@AliasFor(annotation = EventListener.class, attribute = "classes")
Class<?>[] value() default {};
/**
*
*/
@AliasFor(annotation = EventListener.class, attribute = "classes")
Class<?>[] classes() default {};
/**
*
*/
String condition() default "";
}
TransactionPhase枚举
public enum TransactionPhase {
// 指定目标方法在事务commit之前执行
BEFORE_COMMIT,
// 指定目标方法在事务commit之后执行
AFTER_COMMIT,
// 指定目标方法在事务rollback之后执行
AFTER_ROLLBACK,
// 指定目标方法在事务完成时执行,这里的完成是指无论事务是成功提交还是事务回滚了
AFTER_COMPLETION
}