Guava包学习--EventBus

之前没用过这个EventBus,然后看了一下EventBus的源码也没看明白,(-__-)b。反正大概就是弄一个优雅的方式实现了观察者模式吧。慢慢深入学习一下。

观察者模式其实就是生产者消费者的一个变种,就是一边有变化,然后有一个中介,也就是观察者去告诉消费者说:我说哥们啊,他们那边又变了,咱也跟着变吧!

然后观察者要么就是一个抽象类或者一个接口,里面有个update方法,需要每个处理的实例去实现,然后变化的那方持有这些实例,然后挨个去通知。

所以你也看到了,这个持有操作其实就是很不优雅的操作,所以我们用EventBus来看下这个地方到底是怎么实现的优雅的:

可以看到其实Guava中的EventBus的代码很少,只有几个类和注解。

注解有俩个:AllowConcurrentEvents和Subscribe,@AllowConcurrentEvents代表使用线程安全方式获得通知和@Subscribe代表这是一个订阅者,这俩注解和一起使用。

EventBus也就是观察者角色类有两个 EventBus和AsyncEventBus,前面是同步消息,后面支持异步消息。

DeadEvent是指没人关心的消息,可以做一下特殊处理,这个还是很有用,你可以获得有哪些消息根本没人消费过。

Subscriber订阅者对象,具体是哪个EventBus、哪个Listener、哪个方法 3者共同决定一个Subcriber

Dispatcher分发消息给上面那个(那些)Subscriber

SubscriberExceptionContext 订阅者抛出的异常上下文

SubscriberExceptionHandler 接口,处理订阅者抛出的异常

SubscriberRegistry 订阅动作,处理订阅者注册到一个EventBus的动作

 我们来测试一下代码:

public class EventBusMain {
    static final EventBus LINE_1St = new EventBus("first");
    static AsyncEventBus LINE_2Ed = new AsyncEventBus("second", new Executor() {
        @Override
        public void execute(Runnable command) {
            try {
                Thread.sleep(10000L);
                command.run();
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }
    });

    public static void main(String[] args) {
        LINE_1St.register(new EventListener());
        LINE_2Ed.register(new EventListener());

        int cpuNums = Runtime.getRuntime().availableProcessors();
        ExecutorService executorService = Executors.newFixedThreadPool(cpuNums * 1);

        Thread thread1 = new Thread() {
            @Override
            public void run() {
                PromoEvent promoEvent = genPromoEvent();
                LINE_1St.post(promoEvent);
            }
        };
        Thread thread2 = new Thread() {
            @Override
            public void run() {
                LINE_2Ed.post(genDimensionEvent());
            }
        };

        Thread thread3 = new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                    LINE_1St.post(111);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        executorService.execute(thread1);
        executorService.execute(thread2);
        executorService.execute(thread3);
    }

    static PromoEvent genPromoEvent() {
        PromoEvent event = new PromoEvent(1, Lists.newArrayList(1L, 2L, 3L), System.currentTimeMillis(), 0L);
        return event;
    }

    static DimensionEvent genDimensionEvent() {
        DimensionEvent event = new DimensionEvent(100, Lists.newArrayList(100L, 200L, 300L), System.currentTimeMillis(), 0L);
        return event;
    }

然后有两个自定义事件内容,基本上内容是一样的,只是用来测试:

public class PromoEvent {
    private int activityId;
    private List<Long> productIds;
    private Long currentTime;
    private Long triedTimes;

    /**
     * @param activityId
     * @param productIds
     * @param currentTime
     * @param triedTimes
     */
    public PromoEvent(int activityId, List<Long> productIds, Long currentTime, Long triedTimes) {
        super();
        this.activityId = activityId;
        this.productIds = productIds;
        this.currentTime = currentTime;
        this.triedTimes = triedTimes;
    }

    public int getActivityId() {
        return activityId;
    }

    public void setActivityId(int activityId) {
        this.activityId = activityId;
    }

    public List<Long> getProductIds() {
        return productIds;
    }

    public void setProductIds(List<Long> productIds) {
        this.productIds = productIds;
    }

    public Long getCurrentTime() {
        return currentTime;
    }

    public void setCurrentTime(Long currentTime) {
        this.currentTime = currentTime;
    }

    public Long getTriedTimes() {
        return triedTimes;
    }

    public void setTriedTimes(Long triedTimes) {
        this.triedTimes = triedTimes;
    }

    @Override
    public String toString() {
        return "EventTest [activityId=" + activityId + ", productIds=" + productIds + ", currentTime=" + currentTime + ", triedTimes=" + triedTimes
                + "]";
    }

事件监听:

public class EventListener {
    private PromoEvent lastPromoMessage = null;
    private DimensionEvent lastDimensionMessage = null;
    private DeadEvent deadEvent = null;

    @Subscribe
    public void listen(PromoEvent event) {
        lastPromoMessage = event;
        System.out.println("~~~~~~~~~~PromoEvent~~~~~~~~~~~~~");
        System.out.println(event.toString());
    }

    @Subscribe
    public void listen(DimensionEvent event) {
        lastDimensionMessage = event;
        System.out.println("----------DimensionEvent---------");
        System.out.println(event.toString());
    }

    @Subscribe
    public void listen(DeadEvent event) {
        deadEvent = event;
        System.out.println("===========DeadEvent=============");
        System.out.println(event.toString());
    }

    public PromoEvent getLastPromoMessage() {
        return lastPromoMessage;
    }

    public DimensionEvent getLastDimensionMessage() {
        return lastDimensionMessage;
    }

    public DeadEvent getDeadEvent() {
        return deadEvent;

我们声明了两个Bus总线,用来分别存放消息体:

static final EventBus LINE_1St = new EventBus("first");
static AsyncEventBus LINE_2Ed = new AsyncEventBus("second", new Executor() {····});

然后声明3个线程,分别往同步总线里面放一个消息;延迟5秒往同步线程里面放一个无效消息;然后向延迟10秒的异步线程里面放一条消息;

然后监听器Listener分别处理这几个消息,下面是输出结果:

~~~~~~~~~~PromoEvent~~~~~~~~~~~~~
EventTest [activityId=1, productIds=[1, 2, 3], currentTime=1453096744555, triedTimes=0]
===========DeadEvent=============
com.google.common.eventbus.DeadEvent@4ffa5d1a
----------DimensionEvent---------
EventTest [activityId=100, productIds=[100, 200, 300], currentTime=1453096744555, triedTimes=0]

  

posted on 2016-01-18 14:00  见习架构师  阅读(882)  评论(0编辑  收藏  举报

导航