乾貨!SpringBoot利用監聽事件,實現異步操做

本文已參與好文召集令活動,點擊查看:後端、大前端雙賽道投稿,2萬元獎池等你挑戰!前端

今天是我在掘金的第五篇文章,感謝閱讀,並但願之後持續關注,我會輸出更多技術乾貨,咱們共同進步!java

之後可能會分爲幾大專題,相似於併發專題,源碼專題,面試專題等(只會分享乾貨)。面試

有興趣的能夠看下我上篇文章:一步一步教你用dockerspring

請出主角:Spring當中的事件機制

沒錯,本節主要講的是Spring中事件機制:ApplicationEventPublisher,實現監聽ApplicationEvent,最後利用事件通知實現通知實現異步操做docker

image.png

一、爲何要實現異步操做。編程

  • 在微服務的狀況下,多個服務互相調用,及其耗時,當咱們不須要此操做返回時,能夠異步執行,調用接口,該接口快速返回,減小接口響應時長。
  • 代碼邏輯性清晰,對於須要多個異步操做的能夠實現事件的統一管理,不用建立線程池,減小資源的消耗

二、編程過程當中有哪些能夠去異步執行的json

  • 全部耗時、且不須要返回的函數
  • 好比記錄日誌操做、發送郵件、短信等操做。

代碼展現(先實戰、後原理)

假如咱們如今有一個需求,購買會員操做!先來分析具體步驟:後端

一、在會員用戶列表添加該用戶(表明該用戶已經具備會員標示)markdown

二、發送具體會員的權益併發

三、給用戶添加積分操做

四、發送短信通知

假若有上四步,那麼咱們能夠將發送短信通知做爲異步操做。

第一步,建立事件

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) {
     
     //建立會員邏輯開始
     
     //一、建立會員用戶
     
     //二、發送會員權益
     
     //三、給用戶添加積分
     
     //4發送短信
     publishMessage("176********",7465388,具體業務參數的json)
     
     //返回結果
     return "開通會員成功";
}
複製代碼

OK,到這裏就大功告成了,總體流程就是這樣,這樣當執行到給用戶添加積分以後,就可直接返回成功,無須等待發送短信操做。

特別注意:在springBoot項目中使用的話,須要在啓動類當中加入註解@EnableAsync

弦外之音

若是感受對你有幫助的話,歡迎,點贊、分享加關注,後續我會輸出更多技術乾貨,咱們共同進步!

歡迎閱讀上篇文章:一步一步教你用docker

相關文章
相關標籤/搜索