详解SpringBoot 发布ApplicationEventPublisher和监听ApplicationEvent事件
资料地址
Spring@Aync
实现方法
- 自定义需要发布的事件类,需要继承ApplicationEvent类或PayloadApplicationEvent
(该类也仅仅是对ApplicationEvent的一层封装) - 使用@EventListener来监听事件
- 使用ApplicationEventPublisher来发布自定义事件(@Autowired注入即可)
/** *自定义保存事件 *@authorpeter *2019/1/2714:59 */ publicclassPersonSaveEventextendsApplicationEvent{ privateDATAdata; publicPersonSaveEvent(DATAsource){ super(source); this.data=source; } publicDATAgetData(){ returndata; } } //发布事件 publicvoidsavePerson(Personperson){ personDao.save(person); publisher.publishEvent(newPersonSaveEvent<>(1)); } //监听事件 @EventListener publicvoidlistenEvent(PersonSaveEventevent){ System.out.println("监听到PersonSaveEvent事件;接收到的值:"+event.getData()+";发布的时间为"+Instant.ofEpochMilli(event.getTimestamp())); }
好处
可以使核心业务与子业务进行解耦,也方便后期的业务的扩展。如新用户注册之后,需要发放优惠券,此时可以在保存用户之后,发布一个新用户的注册成功事件,通过监听该事件来实现发放优惠券的功能。后期新增一个对新用户进行xxx功能,此时可以新写一个监听注册成功事件的监听器,来处理新的业务逻辑,而不需要修改之前的注册逻辑。
注意事项
1、监听器方法中一定要try-catch异常,否则会造成发布事件(有事物的)的方法进行回滚
2、可以使用@Order注解来控制多个监听器的执行顺序,@Order传入的值越小,执行顺序越高
3、对于需要进行事物监听或不想try-catchruntime异常,可以使用@TransactionalEventListener注解
@TransactionalEventListener监听器
在该注解的源码中:
*Iftheeventisnotpublishedwithintheboundariesofamanagedtransaction,the *eventisdiscardedunlessthe{@link#fallbackExecution}flagisexplicitlyset.Ifa *transactionisrunning,theeventisprocessedaccordingtoits{@codeTransactionPhase}.
大意是:如果事件的发布不是在事物(@Transactional)范围内,则监听不到该事件,除非将fallbackExecution标志设置为true(@TransactionalEventListener(fallbackExecution=true));如果在事物中,可以选择在事物的哪个阶段来监听事件,默认在事物提交后监听。
修改监听事物的范围:@TransactionalEventListener(phase=TransactionPhase.AFTER_COMPLETION)
在监听器中重新开一个事物
@TransactionalEventListener(phase=TransactionPhase.AFTER_COMPLETION) publicvoidlistenEvent1(PersonSaveEventevent){ divide(event); } @Transactional(propagation=Propagation.REQUIRES_NEW) publicvoiddivide(PersonSaveEvent event){ System.out.println("监听到PersonSaveEvent事件;接收到的值:"+event.getData()+";接受的时间为"+Instant.ofEpochMilli(event.getTimestamp())); }
以上事件都是同步,如果需要异步则需要开启异步支持,在监听器方法加上@Async注解即可。
/** *@authorpeter *@version1.0 *@date2019/04/1808:47 */ @Configuration @EnableAsync publicclassAsyncEventConfigurationimplementsAsyncConfigurer{ @Override publicExecutorgetAsyncExecutor(){ returnExecutors.newCachedThreadPool(); } }
一旦开始异步执行,方法的异常将不会抛出,只能在方法内部处理。如需在方法外处理异常:Async异常处理在文章最后
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。