Guava eventbus code analysis (1), guavaeventbus

Source: Internet
Author: User
Tags eventbus

Guava eventbus code analysis (1), guavaeventbus

Before analyzing guava eventbus, let's take a look at the traditional observer mode:

The Subject interface is an abstract topic, which is equivalent to an observer. It holds a list of listener observers. The attach method registers the listener in this list, and the detach method deregisters the listener, Y method is used to notify the listener in the list when an event occurs.

Usually, the update method of the listener is called in notify's implementation method.

The Observer is an abstract Observer with an update method. The update method is called by the notify method of a specific topic.

This is a traditional programming method for interfaces. The difference is that eventbus uses an "implicit interface", a java Annotation-based programming method.

The difference is that the ing between this "implicit interface" is generated when the program is running, while the ing between the interface and implementation based on the real meaning is established at compilation. In contrast, "implicit interface" is more flexible

Let's analyze the implicit interface and how the implementation establishes the binding relationship. See the Code:

1 ## SubscriberRegistry class register method 2 void register (Object listener) {3Multimap <Class <?>, Subscriber> listenerMethods = findAllSubscribers (listener );4 5 for (Map. Entry <Class <?>, Collection <Subscriber> entry: listenerMethods. asMap (). entrySet () {6 Class <?> EventType = entry. getKey (); 7 Collection <Subscriber> eventMethodsInListener = entry. getValue (); 8 9 CopyOnWriteArraySet <Subscriber> eventSubscribers = subscribers. get (eventType); 10 11 if (eventSubscribers = null) {12 CopyOnWriteArraySet <Subscriber> newSet = new CopyOnWriteArraySet <Subscriber> (); 13 eventSubscribers = MoreObjects. firstNonNull (14 subscribers. putIfAbsent (eventType, newSet), newSet); 15} 16 17 eventSubscribers. addAll (eventMethodsInListener); 18} 19}

In this method, 3rd lines are useful. The rest of the code is roughly analyzed to facilitate the Mutimap and add the listener Subsriber of the same type of events to the corresponding set, if the set of the Subsriber of the current type event is empty, add an empty set first.

Follow up the above 3rd rows:

 1 /** 2    * Returns all subscribers for the given listener grouped by the type of event they subscribe to. 3    */ 4   private Multimap<Class<?>, Subscriber> findAllSubscribers(Object listener) { 5     Multimap<Class<?>, Subscriber> methodsInListener = HashMultimap.create(); 6     Class<?> clazz = listener.getClass(); 7     for (Method method : getAnnotatedMethods(clazz)) { 8       Class<?>[] parameterTypes = method.getParameterTypes(); 9       Class<?> eventType = parameterTypes[0];10       methodsInListener.put(eventType, Subscriber.create(bus, listener, method));11     }12     return methodsInListener;13   }

In this method, the core method is 7th rows. It gets all the methods with the Subscribe annotation of a specific class. The rest of the code means to get these methods, put them in multi-value map, and then return them.

Follow up the above 7th rows:

1 private static ImmutableList<Method> getAnnotatedMethods(Class<?> clazz) {2     return subscriberMethodsCache.getUnchecked(clazz);3   }

After that, eclipse does not have to deal with it. It is suspected that the internal Anonymous class has called a method to associate it (eclipse's call link to the internal Anonymous class is also incomplete)

Let's take a look at this.

subscriberMethodsCache

1 private static final LoadingCache<Class<?>, ImmutableList<Method>> subscriberMethodsCache =2       CacheBuilder.newBuilder()3           .weakKeys()4           .build(new CacheLoader<Class<?>, ImmutableList<Method>>() {5             @Override6             public ImmutableList<Method> load(Class<?> concreteClass) throws Exception {7               return getAnnotatedMethodsNotCached(concreteClass);8             }9           });

When the load method is called, The getAnnotatedMethodsNOtCached method of the current class is called, followed by this method:

 1 private static ImmutableList<Method> getAnnotatedMethodsNotCached(Class<?> clazz) { 2     Set<? extends Class<?>> supertypes = TypeToken.of(clazz).getTypes().rawTypes(); 3     Map<MethodIdentifier, Method> identifiers = Maps.newHashMap(); 4     for (Class<?> supertype : supertypes) { 5       for (Method method : supertype.getDeclaredMethods()) { 6         if (method.isAnnotationPresent(Subscribe.class) && !method.isSynthetic()) { 7           // TODO(cgdecker): Should check for a generic parameter type and error out 8           Class<?>[] parameterTypes = method.getParameterTypes(); 9           checkArgument(parameterTypes.length == 1,10               "Method %s has @Subscribe annotation but has %s parameters."11                   + "Subscriber methods must have exactly 1 parameter.",12               method, parameterTypes.length);13 14           MethodIdentifier ident = new MethodIdentifier(method);15           if (!identifiers.containsKey(ident)) {16             identifiers.put(ident, method);17           }18         }19       }20     }21     return ImmutableList.copyOf(identifiers.values());22   }

Row 2nd means to get all classes of the current class + the parent class goods interface of the current class, and put them in a Set

4th rows traverse this Set

5th rows traverse all methods of each class

Line 3 calls the isAnnotationPresent Method of the Method to identify the target Method with the @ Subscribe annotation, and the Method cannot be a "composite Method"

Row 3 places the composite Condition Method in map and returns the result in row 21!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.