美文网首页程序员
CDI组件技术(四)—— 难点event

CDI组件技术(四)—— 难点event

作者: NoOneDev | 来源:发表于2016-11-20 22:34 被阅读125次

    CDI 事件机制是整个精髓所在,有点类似于观察者模式
    定义一个Room类型 的一个添加房间的事件类型,名字并不重要,重要的是类型

        @Inject
        @Add
        Event<Room> roomAddEvent;
    

    页面上点击按钮触发事件,事件生产者通过调用fire()方法,并传递"事件对象"从而激活事件处理. 。

        /**
         * 入住房间
         *
         * @return 这里利用JSF的特性:返回空字符串或者null表示刷新当前页面
         */
        public String checkIn(Room room) {
            roomAddEvent.fire(room);
            return null;
        }
    

    这个时候@Observers修饰的订阅者就可以接收事件,并执行任务,并通过@Add这个qualifter来区别唯一事件类型。

        public void onAddRoom(@Observes @Add Room room){
            log.info("add room:{}.",room);
            room.setStatus(RoomStatus.AVAILABLE);
            rooms.add(room);
        }
    

    动态注入事件

    这样如果有多个事件就不需要为每个事件都定义一个Qualifter了。

    roomAddEvent.select(new AnnotationLiteral<Add>(){}).fire(Room);
    

    定义一个有条件的观察者

    默认情况下,在当前上下文如果没有一个观察者的实例,容器将为事件实例化观察者.但我们希望传递给观察者的实例是已经存在于上下文中的观察者.指定一个有条件的观察者的方式是在@Observes注释上添加receive = IF_EXISTS

    public void refreshOnDocumentUpdate(@Observes(receive = IF_EXISTS) @Updated Document d) { ... }
    

    为Qualifter设置成员变量

    可以通过@Qualifter的value值传递信息给observer.

    @Qualifier
    @Target({METHOD, FIELD, PARAMETER, TYPE})
    @Retention(RUNTIME)
    public @interface Role { 
        RoleType value();
    }
    

    订阅事件时候调用

    public void adminLoggedIn(@Observes @Role(ADMIN) LoggedIn event) { ... }
    

    多重qualifiers

    @Inject @Blog Event<Document> blogEvent;
    ...
    if (document.isBlog()) blogEvent.select(newAnnotationLiteral<Updated>(){}).fire(
    

    下面的观察者都可以得到通知

    public void afterBlogUpdate(@Observes @Updated @Blog Document document) { ... }
    public void afterDocumentUpdate(@Observes @Updated Document document) { ... }
    public void onAnyBlogEvent(@Observes @Blog Document document) { ... }
    public void onAnyDocumentEvent(@Observes Document document) { ... }}}
    

    但是下面这个方法不会得到通知,因为@Personal没有包含在事件发生处

    public void afterPersonalBlogUpdate(@Observes @Updated @Personal @Blog Document document) { ... }
    

    事物处理的Event

    1. IN_PROGRESS --- observers被立即通知 (default)
    2. AFTER_SUCCESS --- 在事务成功完成后,observers会被通知.
    3. AFTER_FAILURE --- 在事务完成失败后,observers会被通知.
    4. AFTER_COMPLETION --- observers在交易完成后的阶段被调用
    5. BEFORE_COMPLETION --- observers在交易完成前阶段被调用

    比如下面这个只有事物成功后才会被通知。

    public void refreshCategoryTree(@Observes(during = AFTER_SUCCESS) CategoryUpdateEvent event) { ... }
    

    参考:
    https://my.oschina.net/zhaoqian/blog/265207

    示例代码:
    https://github.com/liuqinyi/weld-tutorial
    https://github.com/liuqinyi/quickstart.git

    相关文章

      网友评论

        本文标题:CDI组件技术(四)—— 难点event

        本文链接:https://www.haomeiwen.com/subject/codypttx.html