在项目开发中,会遇到如下情形:我们自己的服务订阅、接收来自消息队列或者客户端的事件和请求,基于不同的事件采取对应的行动,这种情况下适合应用派发器模式。
主要模块
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 */@Componentpublic class XXXEventDispatcher implements AutoCloseable { @Resource private XXXEventHandlerInitializer initializer; private Maphandlers = 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类
这个类包括具体的业务处理方法,在系统初始化的时候,会将这些业务处理方法的方法引用注册到派发器中。
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 */@Componentpublic 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函数式编程的基础工具,思想就是要讲函数作为参数传递。如下图所示,这些方法引用都是该函数式接口的实现。
代码如下:
package org.java.learn.java8.dispatcher;/** * Created by IntelliJ IDEA. * User: duqi * Date: 2016/11/3 * Time: 22:03 */@FunctionalInterfacepublic 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枚举
这个类显然用于存储事件类型
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: