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

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

主要模塊

  1. XXXEventDispatcher類
  2. 核心類,維護事件類型(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> 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 {
//釋放資源
}
}
/<xxxeventtype>
  1. XXXEventHandlerInitializer類
  2. 這個類包括具體的業務處理方法,在系統初始化的時候,會將這些業務處理方法的方法引用註冊到派發器中。
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:函數式接口
  2. 函數式接口是Java 8 中實現Lambda函數式編程的基礎工具,思想就是要講函數作為參數傳遞。如下圖所示,這些方法引用都是該函數式接口的實現。
Spring Boot項目中使用事件派發器模式

  1. 代碼如下:
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類
  2. 這個類用於存儲入參和返回值,具體情況可以靈活處理。
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枚舉
  2. 這個類顯然用於存儲事件類型
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:https://github.com/duqicauc/LearnJava

Spring Boot 1.x系列

  1. http://www.javaadu.online/?p=487
  2. http://www.javaadu.online/?p=495
  3. http://www.javaadu.online/?p=499
  4. http://www.javaadu.online/?p=515
  5. http://www.javaadu.online/?p=518
  6. http://www.javaadu.online/?p=521

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


分享到:


相關文章: