guava イベントバスを分析する前に、従来のオブザーバー パターンがどのように記述されているかを見てみましょう。
Subject インターフェイスは、オブザーバーと同等の抽象テーマであり、リスナーとオブザーバーのリストを保持し、attach メソッドは次のとおりです。このリストリスナーに登録されている場合、detach メソッドはリスナーをログアウトし、イベント発生時にリスト内のリスナーに通知するために、notify メソッドが使用されます。通常、リスナーの update メソッドは、notify 実装メソッドで呼び出されます。
Observer は、update メソッドを持つ抽象オブザーバーであり、update メソッドは、特定のトピックの Notice メソッドによって呼び出されます。
これはインターフェイスの伝統的なプログラミング方法です。違いは、eventbus が Java アノテーションに基づくプログラミング手法である「暗黙的インターフェイス」を使用することです。この「暗黙的インターフェイス」間の対応関係は、プログラムの実行時に生成され、実際のインターフェイス間の対応関係に基づいています。対照的に、「暗黙的なインターフェイス」はより柔軟です
暗黙的なインターフェイスと実装がどのようにバインディング関係を確立するかを分析してみましょう:
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 }
このメソッドの 3 行目は、コードの残りの部分の大まかな分析で、この Mutimap を容易にし、同じタイプのイベントのリスナー サブスクライバーを、現在のタイプのイベントのサブスクライバーのセットに追加します。が空の場合は、まず空のセットを追加します。
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 }
このメソッドの中心となるメソッドは 7 行目で、特定のクラスの Subscribe アノテーションを持つすべてのメソッドを取得します。このコードの意味は、これらのメソッドを取得し、それらを多値マップに入れてから戻ることです。
これを見てみましょう
1 private static ImmutableList<Method> getAnnotatedMethods(Class<?> clazz) {2 return subscriberMethodsCache.getUnchecked(clazz);3 }
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 });
行 2 は、現在のクラス自体のすべてのクラス + 現在のクラスの親クラスとインターフェイスを取得し、それらを配置することを意味します。 Set 内
5 行目は各クラスのすべてのメソッドを走査します
16 行目で複合条件付きメソッドをマップに配置します。21 行目で Go と Return を実行します
以上がguavaイベントバスサンプルコードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。