在实际项目中,难免会需要增加一些不影响主流程的业务,比如发短信,发邮件,计费,记账等等的操作。可以考虑异步解耦的思路去做,不失为一种优雅的解决方案。这样可以使得代码结构更加清晰,可扩展性更强。如果是在分布式应用下,不用应用之间可以考虑用MQ去做,如果是在单个项目里面的内部消息,可以考虑用spring的TransactionalEventListener去实现。
1,继承ApplicationEvent来定义自定义事件
package com.example.demo.event;
import org.springframework.context.ApplicationEvent;
/**
* 事件定义
*
* @author lxw
* @date 2020-08-19
*/
public class MyEvent extends ApplicationEvent {
/**
* 操作类型
*/
private String operateType;
/**
* 操作明细
*/
private String operateDetail;
public MyEvent(String operateType, String operateDetail) {
super("");
this.operateType = operateType;
this.operateDetail = operateDetail;
}
public String getOperateType() {
return operateType;
}
public void setOperateType(String operateType) {
this.operateType = operateType;
}
public String getOperateDetail() {
return operateDetail;
}
public void setOperateDetail(String operateDetail) {
this.operateDetail = operateDetail;
}
}
2,使用TransactionalEventListener修饰监听回调方法
package com.example.demo.event;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
/**
* 事件监听器
*
* @author lxw
* @date 2020-08-19
*/
@Component
public class MyEventListener {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT, value = MyEvent.class)
public void handle(MyEvent myEvent) {
System.out.println(myEvent);
System.out.println(myEvent.getOperateDetail());
}
}
3,使用ApplicationEventPublisher推送消息
package com.example.demo;
import com.example.demo.event.MyEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan({"com.example.demo.*"})
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Autowired
private ApplicationEventPublisher eventPublisher;
@Override
public void run(String... args) throws Exception {
MyEvent myEvent = new MyEvent("add", "张三做了一个新增的操作");
eventPublisher.publishEvent(myEvent);
}
}