1. 程式人生 > 程式設計 >Spring Boot專案中使用事件派發器模式

Spring Boot專案中使用事件派發器模式

在專案開發中,會遇到如下情形:我們自己的服務訂閱、接收來自訊息佇列或者客戶端的事件和請求,基於不同的事件採取對應的行動,這種情況下適合應用派發器模式。

主要模組

  1. XXXEventDispatcher類 核心類,維護事件型別(EventType)到處理器(handler)的對映(存放在ConcurrentHashMap中);這個類在啟動時,會通過XXXEventHandlerInitializer初始化這個map資料結構;在啟動時,需要訂閱或監聽來自訊息佇列的事件;當對應的事件到達時,該類的dispatch方法會負責將事件分發到具體的處理器方法中進行處理。
package org.java.learn.java8.dispatcher;
import
org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.annotation.PostConstruct; import javax.annotation.Resource; /** * Created by IntelliJ IDEA. * User: duqi * Date: 2016/11/3 * Time: 21:53 */ @Component public class XXXEventDispatcher
implements AutoCloseable
{ @Resource private XXXEventHandlerInitializer initializer; private Map<XXXEventType,XXXEventHandler> handlers = new ConcurrentHashMap<>(); @PostConstruct public void init() { //建立繫結關係; initializer.init(); //監聽事件並派發 dispatch("testMsg"
); } /** * 將XXX事件註冊到派發器 * * @param xxxEventType * @param xxxEventHandler */ public void bind(XXXEventType xxxEventType,XXXEventHandler xxxEventHandler) { this.handlers.put(xxxEventType,((eventType,context) -> { try { xxxEventHandler.handle(eventType,context); } catch (Exception e) { //記錄錯誤日誌 e.printStackTrace(); } //列印處理器執行日誌 })); } /** * 進行事件派發 * @param eventMsg */ private void dispatch(String eventMsg) { //(1) 從eventMsg中獲取eventType; //(2) 根據eventMsg構造eventContext; //(3) 執行具體的處理器方法 } public void close() throws Exception { //釋放資源 } } 複製程式碼
  1. XXXEventHandlerInitializer類 這個類包括具體的業務處理方法,在系統初始化的時候,會將這些業務處理方法的方法引用註冊到派發器中。
package org.java.learn.java8.dispatcher;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2016/11/3
 * Time: 21:56
 */
@Component
public class XXXEventHandlerInitializer {
    @Resource
    private XXXEventDispatcher dispatcher;

    public void init() {
        dispatcher.bind(XXXEventType.event1,this::handleProcess1);
        dispatcher.bind(XXXEventType.event2,this::handleProcess2);
        dispatcher.bind(XXXEventType.event3,this::handleProcess3);
    }

    private void handleProcess1(XXXEventType eventType,XXXEventContext context) {
        //事件1的處理邏輯
    }

    private void handleProcess2(XXXEventType eventType,XXXEventContext context) {
        //事件2的處理邏輯
    }

    private void handleProcess3(XXXEventType eventType,XXXEventContext context) {
        //事件3的處理邏輯
    }
}
複製程式碼
  1. XXXEventHandler:函式式介面 函式式介面是Java 8 中實現Lambda函式語言程式設計的基礎工具,思想就是要講函式作為引數傳遞。如下圖所示,這些方法引用都是該函式式介面的實現。
    函式式介面的實現
    程式碼如下:
package org.java.learn.java8.dispatcher;
/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2016/11/3
 * Time: 22:03
 */
@FunctionalInterface
public interface XXXEventHandler {
    void handle(XXXEventType eventType,XXXEventContext context);
}
複製程式碼
  1. XXXEventContext類 這個類用於儲存入參和返回值,具體情況可以靈活處理。
package org.java.learn.java8.dispatcher;
/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2016/11/3
 * Time: 22:04
 */
public class XXXEventContext {
    private int param1;
    private int param2;

    @Override
    public String toString() {
        return "XXXEventContext{" +
               "param1=" + param1 +
               ",param2=" + param2 +
               '}';
    }
}
複製程式碼
  1. XXXEventType列舉 這個類顯然用於儲存事件型別
package org.java.learn.java8.dispatcher;
/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2016/11/3
 * Time: 22:03
 */
public enum XXXEventType {
    event1,event2,event3
}
複製程式碼

總結:在企業級開發中,有很多典型的應用場景和模式,事件派發器只是其中的一種,希望你也能夠根據自己的實際情況加以應用。本文中提到的程式碼,參見我的github:LearnJava

Spring Boot 1.x系列

  1. Spring Boot的自動配置、Command-line-Runner
  2. 瞭解Spring Boot的自動配置
  3. Spring Boot的@PropertySource註解在整合Redis中的使用
  4. Spring Boot專案中如何定製HTTP訊息轉換器
  5. Spring Boot整合Mongodb提供Restful介面
  6. Spring中bean的scope

本號專注於後端技術、JVM問題排查和優化、Java面試題、個人成長和自我管理等主題,為讀者提供一線開發者的工作和成長經驗,期待你能在這裡有所收穫。

javaadu