业务场景: 有时候需要一个动作之后触发另外一个动作,类似消息的机制。但使用kafka等又太重。 这时候可以使用Spring的事件来处理。比如我这有一个需要触发一个异步任务的业务场景。
具体业务实现
public void publishSyncTaskEvent(SyncTaskEvent event) {
//do something bussiness .....
this.publisher.publishEvent(event); }
监听器
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
import javax.annotation.Resource;
@Async @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT,fallbackExecution = true) public void invokeSyncTask(SyncTaskEvent syncTaskEvent) { try { log.info("异步线程触发syncTask执行:{}", JsonUtils.obj2JsonStr(syncTaskEvent)); // do something bussiness } catch (Exception e) { log.error("异步线程触发syncTask执行异常", e); } }
@EventListener是常规事件监听器
Spring还有针对事务的的事件监听器@TransactionalEventListener,事务监听器可以绑定到事务的阶段。比如事务提交成功或回滚后才触发,
@TransactionalEventListener包装了@EventListener注解,是普通监听器的加强,但监听器方法是通过回调触发的,即在事务进行gcommit或者rollback的时候会回调监听器方法进行回调。
发布方式和普通事件的发布方式是一样的,但事务事件必须在事务中发布。如果发布了“事务事件”,并且事件类型和某些普通监听器监听的事件类型一致,那么普通监听器也会被触发
@TransactionalEventListener和@EventListener一样,都是同步处理,即是同一个线程处理事件和发布事件的,所以还会阻塞线程,但是可以使用@Async进行异步任务处理,比如上面的例子。
在默认情况下仅仅会被事务中发布的事件触发,如果需要在没有事务也能当作普通时间监听器触发,那么需要将fallbackExecution属性设置为true。
本文来自博客园,作者:茄子_2008,转载请注明原文链接:https://www.cnblogs.com/xd502djj/p/16523860.html