請出主角:Spring當中的事件機制
沒錯,本節主要講的是Spring中事件機制:ApplicationEventPublisher,實現監聽ApplicationEvent,最后利用事件通知實現通知實現異步操作
1、為什么要實現異步操作
- 在微服務的情況下,多個服務互相調用,及其耗時,當我們不需要此操作返回時,可以異步執行,調用接口,該接口快速返回,減少接口響應時長。
- 代碼邏輯性清晰,對於需要多個異步操作的可以實現事件的統一管理,不用創建線程池,減少資源的消耗
2、編程過程中有哪些可以去異步執行的
- 所有耗時、且不需要返回的函數
- 比如記錄日志操作、發送郵件、短信等操作
代碼展示(先實戰、后原理)
假如我們現在有一個需求,購買會員操作!先來分析具體步驟:
1、在會員用戶列表添加該用戶(代表該用戶已經具有會員標示)
2、發送具體會員的權益
3、給用戶添加積分操作
4、發送短信通知
假如有上四步,那么我們可以將發送短信通知作為異步操作。
第一步,創建事件
public class SendMessageEvent extends ApplicationEvent { private SendMessageEventDto sendMessageEventDto; public SendMessageEvent(Object source) { super(source); } public SendMessageEvent(Object source,SendMessageEventDto dto){ super(source); this.sendMessageEventDto = dto; } public SendMessageEventDto getDto(){ return sendMessageEventDto; } public void setDto(SendMessageEventDto dto){ this.sendMessageEventDto = dto; } public class SendMessageEventDto{ /** * 手機號 */ private Integer userId; /** * 手機號 */ private String mobile; /** * 短信模板參數數據體 */ private String data; public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public String getData() { return data; } public void setData(String data) { this.data = data; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } } }
上面代碼中首先定義發送短信的一個實體(SendMessageEventDto),將這個實體交給定義的事件管理(SendMessageEvent),該事件繼承spring的ApplicationEvent
第二步,將事件通過spring發布,由spring監聽該事件
@Autowired private ApplicationEventPublisher applicationEventPublisher; /** * 組裝數據體異步發送短信 * @param mobile 手機號 * @param userId 用戶ID * @param jsonObject 短信所需參數 */ public void publishMessage(String mobile,Integer userId,JSONObject jsonObject){ SendMessageEvent event = new SendMessageEvent(this); SendMessageEvent.SendMessageEventDto dto = event.new SendMessageEventDto(); dto.setData(jsonObject.toString()); //具體業務的數據體 dto.setMobile(mobile); dto.setUserId(userId); event.setDto(dto); //將事件交給spring監聽 applicationEventPublisher.publishEvent(event); }
第三步,讓具體業務持有該事件,並設置被監聽狀態
public interface SendMessageEventListener { //發送短信 void sendMessage(SendMessageEvent sendMessageEvent); }
@Component public class SendMessageEventListenerImpl implements SendMessageEventListener { private Logger logger = LoggerFactory.getLogger(SendMessageEventListenerImpl.class); @Autowired private MiniProgramClient miniProgramClient; @Override @Async @EventListener public void sendMessage(SendMessageEvent sendMessageEvent) { try { SendMessageEvent.SendMessageEventDto dto = sendMessageEvent.getDto(); logger.error("發送短信通知開始 -> 數據體為 -> "+ JSON.toJSONString(dto)); MarketMessageDto messageDto = new MarketMessageDto(); messageDto.setUserId(dto.getUserId()); messageDto.setData(dto.getData()); messageDto.setMobile(dto.getMobile()); //調用短信服務,發送短信 miniProgramClient.sendMarketMsg(messageDto); }catch (Exception e){ e.getMessage(); e.printStackTrace(); } } }
這里特別注意的是,必須在需要被監聽的方法上加上 @EventListener, 然后開啟異步 @Async
演示調用,大功告成
public static void main(String[] args) { //創建會員邏輯開始 //1、創建會員用戶 //2、發送會員權益 //3、給用戶添加積分 //4發送短信 publishMessage("176********",7465388,具體業務參數的json) //返回結果 return "開通會員成功"; }
OK,到這里就大功告成了,整體流程就是這樣,這樣當執行到給用戶添加積分之后,就可直接返回成功,無須等待發送短信操作。
特別注意:在springBoot項目中使用的話,需要在啟動類當中加入注解@EnableAsync
博文轉載自掘金博文:
https://juejin.cn/post/6985049438540529694