Spring Boot項目中使用事件派發器模式

在項目開發中,會遇到以下情形:咱們本身的服務訂閱、接收來自消息隊列或者客戶端的事件和請求,基於不一樣的事件採起對應的行動,這種狀況下適合應用派發器模式。java

主要模塊

  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:LearnJavagit

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面試題、我的成長和自我管理等主題,爲讀者提供一線開發者的工做和成長經驗,期待你能在這裏有所收穫。github

javaadu
相關文章
相關標籤/搜索