SpringBoot 发布ApplicationEventPublisher和监听ApplicationEvent事件

资料地址
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、对于需要进行s事务监听或不想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 异常处理在文章最后

  • 4
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中,我们可以使用ApplicationEventPublisher发布自定义事件。下面是一个简单的使用案例: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; @Component public class MyEventPublisher { @Autowired private ApplicationEventPublisher applicationEventPublisher; public void publishEvent(final String message) { System.out.println("Publishing custom event. "); MyEvent customSpringEvent = new MyEvent(this, message); applicationEventPublisher.publishEvent(customSpringEvent); } } ``` 在上面的代码中,我们首先注入ApplicationEventPublisher,然后定义了一个publishEvent方法,该方法接受一个字符串参数message。在该方法中,我们创建了一个自定义事件MyEvent,并使用ApplicationEventPublisher发布了该事件。 下面是自定义事件MyEvent的定义: ```java import org.springframework.context.ApplicationEvent; public class MyEvent extends ApplicationEvent { private String message; public MyEvent(Object source, String message) { super(source); this.message = message; } public String getMessage() { return message; } } ``` 在上面的代码中,我们继承了ApplicationEvent,并添加了一个message属性和相应的getter方法。 最后,我们需要定义一个事件监听器来处理自定义事件。下面是一个简单的事件监听器: ```java import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class MyEventListener { @EventListener public void onApplicationEvent(MyEvent event) { System.out.println("Received spring custom event - " + event.getMessage()); } } ``` 在上面的代码中,我们使用@EventListener注解来标记onApplicationEvent方法,该方法接受一个MyEvent参数。当MyEvent事件发布时,该方法将被调用,并输出事件的message属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值