美文网首页java
Guava eventBus 关于@AllowConcurren

Guava eventBus 关于@AllowConcurren

作者: guli_2018 | 来源:发表于2017-10-26 16:42 被阅读204次

背景

以下带有@Subscribe的方法简称订阅方法。
@AllowConcurrentEvents的作用就是当使用多线程模式的时候,标记订阅的方法是线程安全的。使之EventBus可以针对同个subscribe方法进行多线程。简单链接:http://www.cnblogs.com/whitewolf/p/4132840.html

经历

但当@Subscribe方法存在继承逻辑时,坑就出现了。荔枝:

package eh;

import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

/**
 * Created by shenhj on 2017/10/26.
 */
public class EventBusTest {

    public static void main(String[] args) {
        EventBus eventBus = new EventBus();
        eventBus.register(new EventListener1());
        eventBus.post(1);
        eventBus.post(1L);
        eventBus.post("hello");
    }
    public static class EventListener1 implements EventListener{
        public void listenInteger(Integer i) {//此方法不会被加入eventBus的loadingCache,父类方法取代之
            System.out.println(i);
        }
        @Subscribe
        public void listenLong(Long l) {//此方法取代父类方法加入eventBus的loadingCache
            System.out.println(l);
        }
        @Subscribe
        @AllowConcurrentEvents
        public void listenString(String string) {//此方法取代父类方法加入eventBus的loadingCache
            System.out.println(string);
        }
    }
    public  interface EventListener {
        @Subscribe
        @AllowConcurrentEvents
        void listenInteger(Integer i);

        @Subscribe
        @AllowConcurrentEvents
        void listenLong(Long i);

        @Subscribe
        @AllowConcurrentEvents
        void listenString(String string);
    }
}

eventBus在register方法时会去加载带有@Subscribe的方法到loadingCache。又由于jvm的类加载机制,子类的方法会优先被遍历,导致带有@Subscribe的子类方法会取代父类方法加载到loadingCache,使父类方法上的@AllowConcurrentEvents注解无效。具体eventBus是怎么遍历,请看代码:

private static ImmutableList<Method> getAnnotatedMethodsInternal(Class<?> clazz) {
    Set<? extends Class<?>> supers = TypeToken.of(clazz).getTypes().rawTypes();
    Map<MethodIdentifier, Method> identifiers = Maps.newHashMap();
    //向上遍历所有相关的注册类,
    // (class eh.EventBusTest$EventListener1)->(interface eh.EventBusTest$EventListener)->(class java.lang.Object)
    for (Class<?> superClazz : supers) {
      for (Method superClazzMethod : superClazz.getMethods()) {
        if (superClazzMethod.isAnnotationPresent(Subscribe.class)
            && !superClazzMethod.isBridge()) {//桥接方法适用与泛型方法的override
          Class<?>[] parameterTypes = superClazzMethod.getParameterTypes();
          if (parameterTypes.length != 1) {
            throw new IllegalArgumentException("Method " + superClazzMethod
                + " has @Subscribe annotation, but requires " + parameterTypes.length
                + " arguments.  Event subscriber methods must require a single argument.");
          }

          MethodIdentifier ident = new MethodIdentifier(superClazzMethod);
          if (!identifiers.containsKey(ident)) {//用方法名和参数类型做判断
            identifiers.put(ident, superClazzMethod);
          }
        }
      }
    }
    return ImmutableList.copyOf(identifiers.values());
  }

推荐

@AllowConcurrentEvents@Subscribe一同使用

相关文章

  • Guava eventBus 关于@AllowConcurren

    背景 以下带有@Subscribe的方法简称订阅方法。@AllowConcurrentEvents的作用就是当使用...

  • Guava EventBus

    http://www.baeldung.com/guava-eventbus

  • Guava EventBus

    我称其为单块架构的利器 前言 在设计模式中, 有一种叫做发布/订阅模式, 即某事件被发布, 订阅该事件的角色将自动...

  • Guava——EventBus

    EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监...

  • Guava - EventBus(事件总线)

    Guava在guava-libraries中为我们提供了事件总线EventBus库,它是事件发布订阅模式的实现,让...

  • 【Guava学习】EventBus

    1,简单使用 首先引入guave的依赖; 再来看一下基础的使用: 首先需要一个总线EventBus,直接new出来...

  • Guava学习——EventBus

    学习Eventbus的相关知识,留存记录,待以后查看。 环境说明:windows7/JDK7/guava-18.0...

  • Guava之EventBus

    EventBus 采用推的方式将消息发送给订阅者 1)Listener存在继承关系 AListener exte...

  • guava EventBus使用

    EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监...

  • Guava之EventBus源码

    最近需要使用事件驱动,打算使用EventBus管理事件的注册和分发。于是仔细阅读了下Guava的EventBus实...

网友评论

    本文标题:Guava eventBus 关于@AllowConcurren

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