事件服务(Event)
事件服务,通过事件的注册、订阅和广播完成事件消息的处理,目的是为了减少代码侵入,降低模块之间的业务耦合度,事件消息采用队列存储,采用多线程接口回调实现消息及消息上下文对象的传输,支持同步和异步两种处理模式;
框架事件初始化配置参数
#------------------------------------- # 框架事件初始化参数 #------------------------------------- # 默认事件触发模式(不区分大小写),取值范围:NORMAL-同步执行,ASYNC-异步执行,默认为ASYNC ymp.event.default_mode= # 事件管理提供者接口实现,默认为net.ymate.platform.core.event.impl.DefaultEventProvider ymp.event.provider_class= # 事件线程池初始化大小,默认为Runtime.getRuntime().availableProcessors() ymp.event.thread_pool_size= # 事件配置扩展参数,xxx表示自定义参数名称,vvv表示参数值 ymp.event.params.xxx=vvv
YMP核心事件对象
-
ApplicationEvent:框架事件
APPLICATION_INITED - 框架初始化 APPLICATION_DESTROYED - 框架销毁
-
ModuleEvent:模块事件
MODULE_INITED - 模块初始化 MODULE_DESTROYED - 模块销毁
注:以上只是YMP框架核心中包含的事件对象,其它模块中包含的事件对象将在其相应的文档描述中阐述;
事件的订阅
-
方式一:通过代码手动完成事件的订阅
public static void main(String[] args) throws Exception { YMP.get().init(); try { // 订阅模块事件 YMP.get().getEvents().registerListener(ModuleEvent.class, new IEventListener<ModuleEvent>() { @Override public boolean handle(ModuleEvent context) { switch (context.getEventName()) { case MODULE_INITED: // 注意:这段代码是不会被执行的,因为在我们进行事件订阅时,模块的初始化动作已经完成 System.out.println("Inited :" + context.getSource().getName()); break; case MODULE_DESTROYED: System.out.println("Destroyed :" + context.getSource().getName()); break; } return false; } }); } finally { YMP.get().destroy(); } }
-
方式二:通过
@EventRegister
注解和IEventRegister接口实现事件的订阅// 首先创建事件注册类,通过实现IEventRegister接口完成事件的订阅 // 通过@EventRegister注解,该类将在YMP框架初始化时被自动加载 @EventRegister public class DemoEventRegister implements IEventRegister { public void register(Events events) throws Exception { // 订阅模块事件 events.registerListener(ModuleEvent.class, new IEventListener<ModuleEvent>() { @Override public boolean handle(ModuleEvent context) { switch (context.getEventName()) { case MODULE_INITED: System.out.println("Inited :" + context.getSource().getName()); break; case MODULE_DESTROYED: System.out.println("Destroyed :" + context.getSource().getName()); break; } return false; } }); // // ... 还可以添加更多的事件订阅代码 } } // 框架启动测试 public static void main(String[] args) throws Exception { YMP.get().init(); try { // Do Nothing... } finally { YMP.get().destroy(); } }
自定义事件
YMP的事件对象必须实现IEvent接口的同时需要继承EventContext对象,下面的代码就是一个自定义事件对象:
-
创建自定义事件对象
public class DemoEvent extends EventContext<Object, DemoEvent.EVENT> implements IEvent { public enum EVENT { CUSTOM_EVENT_ONE, CUSTOM_EVENT_TWO } public DemoEvent(Object owner, Class<? extends IEvent> eventClass, EVENT eventName) { super(owner, eventClass, eventName); } }
说明:EventContext的注解中的第一个参数代表事件源对象类型,第二个参数是指定用于事件监听事件名称的枚举类型;
-
注册自定义事件
YMP.get().getEvents().registerEvent(DemoEvent.class);
-
订阅自定义事件
事件订阅(或监听)需实现IEventListener接口,该接口的handle方法返回值在异步触发模式下将影响事件监听队列是否终止执行,同步触发模式下请忽略此返回值;
YMP.get().getEvents().registerListener(DemoEvent.class, new IEventListener<DemoEvent>() { public boolean handle(DemoEvent context) { switch (context.getEventName()) { case CUSTOM_EVENT_ONE: System.out.println("CUSTOM_EVENT_ONE"); break; case CUSTOM_EVENT_TWO: System.out.println("CUSTOM_EVENT_TWO"); break; } return false; } });
当然,也可以通过
@EventRegister
注解和IEventRegister接口实现自定义事件的订阅;注:当某个事件被触发后,订阅(或监听)该事件的接口被回调执行的顺序是不能被保证的;
-
触发自定义事件
// 采用默认模式触发事件 YMP.get().getEvents().fireEvent(new DemoEvent(YMP.get(), DemoEvent.class, DemoEvent.EVENT.CUSTOM_EVENT_ONE)); // 采用异步模式触发事件 YMP.get().getEvents().fireEvent(Events.MODE.ASYNC, new DemoEvent(YMP.get(), DemoEvent.class, DemoEvent.EVENT.CUSTOM_EVENT_TWO));
-
示例测试代码:
public static void main(String[] args) throws Exception { YMP.get().init(); try { // 注册自定义事件对象 YMP.get().getEvents().registerEvent(DemoEvent.class); // 注册自定义事件监听 YMP.get().getEvents().registerListener(DemoEvent.class, new IEventListener<DemoEvent>() { public boolean handle(DemoEvent context) { switch (context.getEventName()) { case CUSTOM_EVENT_ONE: System.out.println("CUSTOM_EVENT_ONE"); break; case CUSTOM_EVENT_TWO: System.out.println("CUSTOM_EVENT_TWO"); break; } return false; } }); // 采用默认模式触发事件 YMP.get().getEvents().fireEvent(new DemoEvent(YMP.get(), DemoEvent.class, DemoEvent.EVENT.CUSTOM_EVENT_ONE)); // 采用异步模式触发事件 YMP.get().getEvents().fireEvent(Events.MODE.ASYNC, new DemoEvent(YMP.get(), DemoEvent.class, DemoEvent.EVENT.CUSTOM_EVENT_TWO)); } finally { YMP.get().destroy(); } }