详解SpringBoot 发布ApplicationEventPublisher和监听ApplicationEvent事件

网友投稿 1048 2023-01-05


详解SpringBoot 发布ApplicationEventPublisher和监听ApplicationEvent事件

资料地址

Spring @Aync

实现方法

自定义需要发布的事件类,需要继承ApplicationEvent类或PayloadApplicationEvent(该类也仅仅是对ApplicationEvent的一层封装)

使用@EventListener来监听事件

使用ApplicationEventPublisher来发布自定义事件(@Autowired注入即可)

/**

* 自定义保存事件

* @author peter

* 2019/1/27 14:59

*/

public class PersonSaveEvent extends ApplicationEvent {

private DATA data;

public PersonSaveEvent(DATA source) {

super(source);

this.data = source;

}

public DATA getData() {

return data;

}

}

//发布事件

public void savePerson(Person person){

personDao.savhttp://e(person);

publisher.publishEvent(new PersonSaveEvent<>(1));

}

//监听事件

@EventListener

public void listenEvent(PersonSaveEvent event) {

System.out.println("监听到PersonSaveEvent事件; 接收到的值:" + event.getData() + ";发布的时间为" + Instant.ofEpochMilli(event.getTimestamp()));

}

好处

可以使核心业务与子业务进行解耦,也方便后期的业务的扩展。如新用户注册之后,需要发放优惠券,此时可以在保存用户之后,发布一个新用户的注册成功事件,通过监听该事件来实现发放优惠券的功能。后期新增一个对新用户进行xxx功能,此时可以新写一个监听注册成功事件的监听器,来处理新的业务逻辑,而不需要修改之前的注册逻辑。

注意事项

1、监听器方法中一定要try-catch异常,否则会造成发布事件(有事物的)的方法进行回滚

2、可以使用@Order注解来控制多个监听器的执行顺序,@Order传入的值越小,执行顺序越高

3、对于需要进行事物监听或不想try-catch runtime异常,可以使用@TransactionalEventListener注解

@TransactionalEventListener 监听器

在该注解的源码中:

*

If the event is not published within the boundaries of a managed transaction, the

* event is discarded unless the {@link #fallbackExecution} flag is explicitly set. If a

* transactHcJzayion is running, the event is processed according to its {@code TransactionPhase}.

大意是:如果事件的发布不是在事物(@Transactional)范围内,则监听不到该事件,除非将fallbackExecution标志设置为true(@TransactionalEHcJzayventListener(fallbackExecution = true));如果在事物中,可以选择在事物的哪个阶段来监听事件,默认在事物提交后监听。

修改监听事物的范围:@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)

在监听器中重新开一个事物

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)

public void listenEvent1(PersonSaveEvent event) {

divide(event);

}

@Transactional(propagation = Propagation.REQUIRES_NEW)

public void divide(PersonSaveEvent event) {

System.out.println("监听到PersonSaveEvent事件; 接收到的值:" + event.getData() + ";接受的时间为" + Instant.ofEpochMilli(event.getTimestamp()));

}

以上事件都是同步,如果需要异步则需要开启异步支持,在监听器方法加上@Async 注解即可。

/**

* @author peter

* @version 1.0

* @date 2019/04/18 08:47

*/

@Configuration

@EnableAsync

public class AsyncEventConfiguration implements AsyncConfigurer {

@Override

public Executor getAsyncExecutor() {

return Executors.newCachedThreadPool();

}

}

一旦开始异步执行,方法的异常将不会抛出,只能在方法内部处理。如需在方法外处理异常:Async 异常处理在文章最后


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:为什么要用微服务网关(微服务统一网关)
下一篇:催收系统接口设计规范最新(催收系统接口设计规范最新文件)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~