Spring Event 可以简单实现业务解耦,从Spring 4.2以后,事件处理不用实现ApplicationListener 的 onApplicationEvent方法了,使用注解@EventListener可以自动关联相关的ApplicationListener
@EventListener(condition = "#event.shouldSendMsg")
public void afterRegisterSendMail(MessageEvent event) {
mailService.send(event.getUser().getEmail(),"register successful");
}
事务绑定事件
标准的事件模型在一些业务上能很好的满足需求,例如异步化处理,不干扰主线程执行等,不论事务被提交或回滚,都能正常执行.但是如果我们只是希望事务被提交后,再执行事件呢?
例如,用户注册成功后添加一个发送邮件的事件,或者推送消息,或者短信,这时候需要保存数据库后,再进行这些操作.但是万一事务提交失败数据库事务会回滚,这时候如果用户收到邮件,那可惨淡了!
在Spring事务管理中, 事务是配置注解声明的 (@Transactional) 提交操作将在方法结束后执行. 提交是自动自行的(transaction.commit()). 以下是一些解决方式:
解决方案1(
@EventListener
public void afterRegisterSendMail(MessageEvent event) {
// Spring 4.2 之前
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
internalSendMailNotification(event);
}
});
}
上面的代码将在事务提交后执行.如果在非事务context中将抛出java.lang.IllegalStateException: Transaction synchronization is not active,
@EventListener
public void afterRegisterSendMail(MessageEvent event) {
// Spring 4.2 之前
if (TransactionSynchronizationManager.isActualTransactionActive()) {
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
mailService.send(event);
}
});
} else {
mailService.send(event);
}
}
这样无论是否有事务都能兼容啦. 下面介绍Spring 4.2以后的简化处理:
解决方案2(Spring 4.2 +)
Spring 4.2除了EventListener之外,额外提供了新的注解TransactionalEventListener
@TransactionalEventListener
public void afterRegisterSendMail(MessageEvent event) {
mailService.send(event);
}
这个注解的强大之处在于可一直控制事务的 before/after commit, after rollback ,after completion (commit或 rollback). 默认情况下,在事务中的Event将会被执行,其他情况不触发.
在非事务context下,如果也想执行,启用参数:fallbackExecution=true,
@TransactionalEventListener(fallbackExecution = true)
public void afterRegisterSendMail(MessageEvent event) {
mailService.send(event);
}
https://my.oschina.net/osgit/blog/883823