在項目開發中,會遇到以下情形:咱們本身的服務訂閱、接收來自消息隊列或者客戶端的事件和請求,基於不一樣的事件採起對應的行動,這種狀況下適合應用派發器模式。java
XXXEventDispatcher類
核心類,維護事件類型(EventType)處處理器(handler)的映射(存放在ConcurrentHashMap中);這個類在啓動時,會經過XXXEventHandlerInitializer初始化這個map數據結構;在啓動時,須要訂閱或監聽來自消息隊列的事件;當對應的事件到達時,該類的dispatch方法會負責將事件分發到具體的處理器方法中進行處理。git
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 { //釋放資源 } }
XXXEventHandlerInitializer類
這個類包括具體的業務處理方法,在系統初始化的時候,會將這些業務處理方法的方法引用註冊到派發器中。github
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的處理邏輯 } }
XXXEventHandler:函數式接口
函數式接口是Java 8 中實現Lambda函數式編程的基礎工具,思想就是要講函數做爲參數傳遞。以下圖所示,這些方法引用都是該函數式接口的實現。spring
代碼以下:編程
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); }
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 + '}'; } }
XXXEventType枚舉
這個類顯然用於存儲事件類型ide
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函數式編程