我们日常开发过程中经常会遇到一些代码逻辑不想耦合在一起,就想要解耦,这种情形下,我们可以使用spring的事件通知机制,方法如下:
创建一个通知的事件消息体:
@Data
public class BannerTransferEvent extends ApplicationEvent {
private BannerTransfer transfer;
public BannerTransferEvent(Object source,BannerTransfer transfer) {
super(source);
this.transfer = transfer;
}
}
通知的事件消息体需继承ApplicationEvent 类。
创建一个事件的监听者,
有两种,下面是使用了注解的方式:
一:普通的事件监听者:
@Slf4j
@Component
public class BannerTransferListener {
@EventListener
public void handleGameChange(BannerTransferEvent event) {
//TODO deal event
}
}
二:事物的事件监听者:
事务的监听方式主要用作,我们在一些事务代码中,有一些代码逻辑想要解耦,但是由于是事物中的功能,我们要保证事物性,或者我们有时候,需要在事务真实提交之后,在触发相应的代码,都可以使用下面的事物的事件监听者。后面的phase有四种执行时机:
BEFORE_COMMIT:事务提交之前执行
AFTER_COMMIT:事务提交之后执行
AFTER_ROLLBACK:事务回滚之后执行
AFTER_COMPLETION:事务完成之后执行
public class BannerTransferListener {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleTransactionalBannerTransfer(BannerTransferEvent event) {
//TODO deal event
}
}
发送事件通知
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void doSomeThing(){
//do some thing
BannerTransfer transfer = new BannerTransfer();
applicationEventPublisher.publishEvent(new BannerTransferEvent(this,transfer));
//do some thing
}
//事物处理过程中可以发送
@Transactional(rollbackFor = Exception.class)
public void doSomeThing(){
//do some thing
BannerTransfer transfer = new BannerTransfer();
applicationEventPublisher.publishEvent(new BannerTransferEvent(this,transfer));
//do some thing
}
注意:
如果有两个监听者监听同一个通知事件,一个是事物的方式,一个是普通的方式,当在事物逻辑中发送消息时,两个事件都能接收到消息,当在普通逻辑中发送消息时,只有普通消息监听者能够收到消息。最好的方式就是不要两个监听者监听同一个通知事件,如果有业务需要这种,可以在消息体内加type区分。