欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-20 20:30:24
资料地址 spring @aync 实现方法 自定义需要发布的事件类,需要继承applicationevent类或payloadapplication...

资料地址

spring @aync

实现方法

  1. 自定义需要发布的事件类,需要继承applicationevent类或payloadapplicationevent<t>(该类也仅仅是对applicationevent的一层封装)
  2. 使用@eventlistener来监听事件
  3. 使用applicationeventpublisher来发布自定义事件(@autowired注入即可)
/**
 * 自定义保存事件
 * @author peter
 * 2019/1/27 14:59
 */
public class personsaveevent<data> 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.save(person);
  publisher.publishevent(new personsaveevent<>(1));
}
//监听事件
@eventlistener
public void listenevent(personsaveevent<integer> event) {
   system.out.println("监听到personsaveevent事件; 接收到的值:" + event.getdata() + ";发布的时间为" + instant.ofepochmilli(event.gettimestamp()));
}

好处

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

注意事项

1、监听器方法中一定要try-catch异常,否则会造成发布事件(有事物的)的方法进行回滚
2、可以使用@order注解来控制多个监听器的执行顺序,@order传入的值越小,执行顺序越高
3、对于需要进行事物监听或不想try-catch runtime异常,可以使用@transactionaleventlistener注解

@transactionaleventlistener 监听器

在该注解的源码中:

 * <p>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
 * transaction is running, the event is processed according to its {@code transactionphase}.

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

修改监听事物的范围:@transactionaleventlistener(phase = transactionphase.after_completion)

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

 @transactionaleventlistener(phase = transactionphase.after_completion)
  public void listenevent1(personsaveevent<integer> event) {
    divide(event);
  }
  @transactional(propagation = propagation.requires_new)
  public void divide(personsaveevent<integer> 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 异常处理在文章最后

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。