活動服務(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();
    }
}
################