首页 > 代码库 > Guava源码学习(五)EventBus
Guava源码学习(五)EventBus
基于版本:Guava 22.0
Wiki:EventBus
0. EventBus简介
提供了发布-订阅模型,可以方便的在EventBus上注册订阅者,发布者可以简单的将事件传递给EventBus,EventBus会自动将事件传递给相关联的订阅者。
支持同步/异步模式。
只能用于线程间通信。
1. EventBus类图
EventBus是同步实现
AsyncEventBus是异步实现
2. 代码实例
EventBus eventBus = new EventBus(); eventBus.register(new Object() { @Subscribe public void listen(Object subReport) throws Exception { System.out.println("receive object event!"); } @Subscribe public void listen(Integer subReport) throws Exception { System.out.println("receive integer event!"); } }); eventBus.post(Integer.valueOf(1));
这段代码的输出如下:
receive integer event!
receive object event!
3. EventBus.register()
EventBus.register /** * Registers all subscriber methods on {@code object} to receive events. * * @param object object whose subscriber methods should be registered. */ public void register(Object object) { subscribers.register(object); } SubscriberRegistry.register /** * Registers all subscriber methods on the given listener object. */ void register(Object listener) { Multimap<Class<?>, Subscriber> listenerMethods = findAllSubscribers(listener);//获取传入的listener中含有的所有的监听者 for (Map.Entry<Class<?>, Collection<Subscriber>> entry : listenerMethods.asMap().entrySet()) { Class<?> eventType = entry.getKey();//监听的事件类型 Collection<Subscriber> eventMethodsInListener = entry.getValue();//对应的监听器本身 CopyOnWriteArraySet<Subscriber> eventSubscribers = subscribers.get(eventType); if (eventSubscribers == null) { CopyOnWriteArraySet<Subscriber> newSet = new CopyOnWriteArraySet<Subscriber>(); eventSubscribers = MoreObjects.firstNonNull(subscribers.putIfAbsent(eventType, newSet), newSet); } eventSubscribers.addAll(eventMethodsInListener); } } /** * Returns all subscribers for the given listener grouped by the type of event they subscribe to. 分析传入的对象,遍历其中所有含有Subscribe注解而且只含有一个参数的方法,然后将其包装成监听者并返回。 */ private Multimap<Class<?>, Subscriber> findAllSubscribers(Object listener) { Multimap<Class<?>, Subscriber> methodsInListener = HashMultimap.create(); Class<?> clazz = listener.getClass(); for (Method method : getAnnotatedMethods(clazz)) {//getAnnotatedMethods方法最终会调用到下面的SubscriberRegistry.getAnnotatedMethodsNotCached方法,这个方法会用反射处理传入的clazz及其所有的父类,提取出含有Subscribe注解并且有且只有一个参数的方法 Class<?>[] parameterTypes = method.getParameterTypes(); Class<?> eventType = parameterTypes[0];//获取这个方法的唯一参数的Class methodsInListener.put(eventType, Subscriber.create(bus, listener, method));//将EventBus,监听者对象,监听者方法包装一下并放入map,后续触发事件的时候会用到 } return methodsInListener; } SubscriberRegistry.getAnnotatedMethodsNotCached private static ImmutableList<Method> getAnnotatedMethodsNotCached(Class<?> clazz) { Set<? extends Class<?>> supertypes = TypeToken.of(clazz).getTypes().rawTypes();//连clazz的父类也会处理 Map<MethodIdentifier, Method> identifiers = Maps.newHashMap(); for (Class<?> supertype : supertypes) { for (Method method : supertype.getDeclaredMethods()) { if (method.isAnnotationPresent(Subscribe.class) && !method.isSynthetic()) {//含有Subscribe注解,而且不是合成的方法 // TODO(cgdecker): Should check for a generic parameter type and error out Class<?>[] parameterTypes = method.getParameterTypes(); checkArgument( parameterTypes.length == 1, "Method %s has @Subscribe annotation but has %s parameters." + "Subscriber methods must have exactly 1 parameter.", method, parameterTypes.length);//方法必须有且只有一个参数 MethodIdentifier ident = new MethodIdentifier(method); if (!identifiers.containsKey(ident)) { identifiers.put(ident, method); } } } } return ImmutableList.copyOf(identifiers.values()); }
Guava源码学习(五)EventBus
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。