Heim > Java > javaLernprogramm > Detaillierte Erläuterung des Guava-Eventbus-Beispielcodes

Detaillierte Erläuterung des Guava-Eventbus-Beispielcodes

PHP中文网
Freigeben: 2017-06-21 09:25:33
Original
2001 Leute haben es durchsucht

Bevor wir den Guava-Eventbus analysieren, schauen wir uns an, wie das traditionelle Beobachtermuster geschrieben ist:

Die Subjektschnittstelle ist ein abstraktes Thema, das dem Beobachter entspricht und gilt ein Listener Die Liste der Beobachter, die Attach-Methode registriert den Listener in dieser Liste, die Detach-Methode löscht den Listener und die Notify-Methode wird verwendet, um die Listener in der Liste zu benachrichtigen, wenn ein Ereignis auftritt

wird normalerweise aufgerufen in der Notify-Implementierungsmethode Die Update-Methode des Listeners.

Observer ist ein abstrakter Beobachter mit einer Update-Methode. Die Update-Methode wird von der Notify-Methode des spezifischen Themas aufgerufen.

Dies ist eine traditionelle Programmiermethode für Schnittstellen. Der Unterschied besteht darin, dass Eventbus eine „implizite Schnittstelle“ verwendet, eine Programmiermethode, die auf Java Annotation basiert. Der Unterschied besteht darin, dass die Entsprechung dieser „impliziten Schnittstelle“ generiert wird, wenn das Programm ausgeführt wird, und auf der Grundlage der wahren Die Bedeutung der entsprechenden Beziehung zwischen der Schnittstelle und der Implementierung wird zur Kompilierungszeit hergestellt. Im Gegensatz dazu ist die „implizite Schnittstelle“ flexibler.

Lassen Sie uns analysieren, wie die implizite Schnittstelle und die Implementierung die Bindung herstellen. Um die Beziehung zu bestimmen, Schauen Sie sich den Code an:

 1 ##SubscriberRegistry类的register方法 2 void register(Object listener) { 3     Multimap<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   }
Nach dem Login kopieren
Das Nützlichste an dieser Methode ist Zeile 3. Eine grobe Analyse des restlichen Codes soll diese Mutimap erleichtern, die Ereignisse von kombiniert der gleiche Typ Der Listener-Abonnent wird zum entsprechenden Satz hinzugefügt. Wenn der Abonnentensatz des aktuellen Ereignistyps leer ist, fügen Sie zuerst einen leeren Satz hinzu

Folgen Sie der Methode in Zeile 3 oben:

 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   }
Nach dem Login kopieren
Die Kernmethode in dieser Methode ist Zeile 7, die darin besteht, alle Methoden mit Subscribe-Annotation einer bestimmten Klasse abzurufen. Der Rest des Codes bedeutet, diese Methoden abzurufen und einzufügen eine Mehrwertkarte und dann Return.

Folgen Sie der Methode in Zeile 7 oben:

1 private static ImmutableList<Method> getAnnotatedMethods(Class<?> clazz) {2     return subscriberMethodsCache.getUnchecked(clazz);3   }
Nach dem Login kopieren
Danach hat Eclipse keine Möglichkeit mehr, zu folgen . Es wird vermutet, dass es von einer internen anonymen Klasse aufgerufen wird (Eclipse zeigt auch unvollständige Aufruflinks zu internen anonymen Klassen an)

🎜>

Die Lademethode lautet: Beim Aufruf wird die getAnnotatedMethodsNOtCached-Methode der aktuellen Klasse aufgerufen, gefolgt von dieser Methode:
subscriberMethodsCache
Nach dem Login kopieren
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           });
Nach dem Login kopieren

Die zweite Zeile bedeutet, die aktuelle Klasse selbst + die übergeordnete Klasse der aktuellen Klasse abzurufen. Alle Klassen der Schnittstelle werden in einem Set platziert.

Zeile 4 durchläuft dieses Set.
 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   }
Nach dem Login kopieren
Zeile 5 durchläuft alle Methoden von jede Klasse

Zeile 6 ruft auf Methode Die Methode isAnnotationPresent bestimmt, dass die Zielmethode die @Subscribe-Annotation hat und die Methode kann keine „zusammengesetzte Methode“ sein

In Zeile 16 die zusammengesetzte bedingte Methode wird in der Karte platziert und in Zeile 21 zurückgegeben!

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Guava-Eventbus-Beispielcodes. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage