在项目开发中,会遇到如下情形:我们自己的服务订阅、接收来自消息队列或者客户端的事件和请求,基于不同的事件采取对应的行动,这种情况下适合应用派发器模式。
XXXEventDispatcher类
核心类,维护事件类型(EventType)到处理器(handler)的映射(存放在ConcurrentHashMap中);这个类在启动时,会通过XXXEventHandlerInitializer初始化这个map数据结构;在启动时,需要订阅或监听来自消息队列的事件;当对应的事件到达时,该类的dispatch方法会负责将事件分发到具体的处理器方法中进行处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| 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;
@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"); }
public void bind(XXXEventType xxxEventType, XXXEventHandler xxxEventHandler) { this.handlers.put(xxxEventType, ((eventType, context) -> { try { xxxEventHandler.handle(eventType, context); } catch (Exception e) { e.printStackTrace(); } })); }
private void dispatch(String eventMsg) { }
public void close() throws Exception { } }
|
XXXEventHandlerInitializer类
这个类包括具体的业务处理方法,在系统初始化的时候,会将这些业务处理方法的方法引用注册到派发器中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package org.java.learn.java8.dispatcher; import org.springframework.stereotype.Component; import javax.annotation.Resource;
@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) { }
private void handleProcess2(XXXEventType eventType, XXXEventContext context) { }
private void handleProcess3(XXXEventType eventType, XXXEventContext context) { } }
|
XXXEventHandler:函数式接口
函数式接口是Java 8 中实现Lambda函数式编程的基础工具,思想就是要讲函数作为参数传递。如下图所示,这些方法引用都是该函数式接口的实现。
代码如下:
1 2 3 4 5 6 7 8 9 10 11
| package org.java.learn.java8.dispatcher;
@FunctionalInterface public interface XXXEventHandler { void handle(XXXEventType eventType, XXXEventContext context); }
|
XXXEventContext类
这个类用于存储入参和返回值,具体情况可以灵活处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package org.java.learn.java8.dispatcher;
public class XXXEventContext { private int param1; private int param2;
@Override public String toString() { return "XXXEventContext{" + "param1=" + param1 + ", param2=" + param2 + '}'; } }
|
XXXEventType枚举
这个类显然用于存储事件类型
1 2 3 4 5 6 7 8 9 10 11 12
| package org.java.learn.java8.dispatcher;
public enum XXXEventType { event1, event2, event3 }
|
总结
在企业级开发中,有很多典型的应用场景和模式,事件派发器只是其中的一种,希望你也能够根据自己的实际情况加以应用。本文中提到的代码,参见我的github:LearnJava