在项目开发中,会遇到如下情形:我们自己的服务订阅、接收来自消息队列或者客户端的事件和请求,基于不同的事件采取对应的行动,这种情况下适合应用派发器模式。
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 { //释放资源 } }
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的处理逻辑 } }
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); }
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: LearnJava
本号专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。