网站电脑培训班附近有吗,宁夏建设厅官方网站,html在网站开发中的应用,网站后台排版工具前言EventBus的核心思想是观察者模式 (生产/消费者编程模型) 。通过前面的文章我们已经知道#xff0c;如何使用eventBus了。我们需要先定义一个Observer(前文中的EventListener类)#xff0c;然后将其注册到eventBus里#xff0c;通过 Subscribe 定义消息回调函数。那我们先…前言EventBus的核心思想是观察者模式 (生产/消费者编程模型) 。通过前面的文章我们已经知道如何使用eventBus了。我们需要先定义一个Observer(前文中的EventListener类)然后将其注册到eventBus里通过 Subscribe 定义消息回调函数。那我们先看看register(Object object) 和unregister(Object object) 方法。register (Object object) 解析public void register(Object object) {Multimap, EventSubscriber methodsInListener finder.findAllSubscribers(object);subscribersByTypeLock.writeLock().lock();try {subscribersByType.putAll(methodsInListener);} finally {subscribersByTypeLock.writeLock().unlock();}}12345678910publicvoidregister(Objectobject){Multimap,EventSubscribermethodsInListenerfinder.findAllSubscribers(object);subscribersByTypeLock.writeLock().lock();try{subscribersByType.putAll(methodsInListener);}finally{subscribersByTypeLock.writeLock().unlock();}}可以看到是先通过SubscriberFindingStrategy接口里的findAllSubscribers方法获取所有标记了 Subscribe 注解的方法其中该接口的具体实现是AnnotatedSubscriberFinder类。放到一个guava里定义的Multimap里。然后是把获取到的methodsInListener放到一个叫subscribersByType的 guava里定义的SetMultimap里 。public Multimap, EventSubscriber findAllSubscribers(Object listener) {Multimap, EventSubscriber methodsInListener HashMultimap.create();Class clazz listener.getClass();for (Method method : getAnnotatedMethods(clazz)) {Class[] parameterTypes method.getParameterTypes();Class eventType parameterTypes[0];EventSubscriber subscriber makeSubscriber(listener, method);methodsInListener.put(eventType, subscriber);}return methodsInListener;}1234567891011publicMultimap,EventSubscriberfindAllSubscribers(Objectlistener){Multimap,EventSubscribermethodsInListenerHashMultimap.create();Classclazzlistener.getClass();for(Methodmethod:getAnnotatedMethods(clazz)){Class[]parameterTypesmethod.getParameterTypes();ClasseventTypeparameterTypes[0];EventSubscribersubscribermakeSubscriber(listener,method);methodsInListener.put(eventType,subscriber);}returnmethodsInListener;}findAllSubscribers方法里最重要的是methodsInListener它的结构可以简单理解为一个map其中key是eventType在我前文写的例子中就是com.sww.eventbus.domain.MessageEvent其中value是subscriber就是例子中的com.sww.eventbus.listener.EventListener#onMessageEvent。总之一句话就是先通过标记找到所有已经注册进来的观察者然后存放到容器里备用。那unregister就是从容器删除它们unRegister (Object object) 解析public void unregister(Object object) {Multimap, EventSubscriber methodsInListener finder.findAllSubscribers(object);for (Entry, Collection entry :methodsInListener.asMap().entrySet()) {Class eventType entry.getKey();Collection eventMethodsInListener entry.getValue();subscribersByTypeLock.writeLock().lock();try {Set currentSubscribers subscribersByType.get(eventType);if (!currentSubscribers.containsAll(eventMethodsInListener)) {throw new IllegalArgumentException(missing event subscriber for an annotated method. Is object registered?);}currentSubscribers.removeAll(eventMethodsInListener);} finally {subscribersByTypeLock.writeLock().unlock();}}}1234567891011121314151617181920publicvoidunregister(Objectobject){Multimap,EventSubscribermethodsInListenerfinder.findAllSubscribers(object);for(Entry,Collectionentry:methodsInListener.asMap().entrySet()){ClasseventTypeentry.getKey();CollectioneventMethodsInListenerentry.getValue();subscribersByTypeLock.writeLock().lock();try{SetcurrentSubscriberssubscribersByType.get(eventType);if(!currentSubscribers.containsAll(eventMethodsInListener)){thrownewIllegalArgumentException(missing event subscriber for an annotated method. Is object registered?);}currentSubscribers.removeAll(eventMethodsInListener);}finally{subscribersByTypeLock.writeLock().unlock();}}}post( Object event)解析有了观察者下面就是发送事件了阅读过前文会知道是通过eventBus.post(Object event)来发送事件消息。那咱们来看看这个post方法。public void post(Object event) {Set dispatchTypes flattenHierarchy(event.getClass());boolean dispatched false;for (Class eventType : dispatchTypes) {subscribersByTypeLock.readLock().lock();try {Set wrappers subscribersByType.get(eventType);if (!wrappers.isEmpty()) {dispatched true;for (EventSubscriber wrapper : wrappers) {enqueueEvent(event, wrapper);}}} finally {subscribersByTypeLock.readLock().unlock();}}if (!dispatched !(event instanceof DeadEvent)) {post(new DeadEvent(this, event));}dispatchQueuedEvents();}1234567891011121314151617181920212223242526publicvoidpost(Objectevent){SetdispatchTypesflattenHierarchy(event.getClass());booleandispatchedfalse;for(ClasseventType:dispatchTypes){subscribersByTypeLock.readLock().lock();try{SetwrapperssubscribersByType.get(eventType);if(!wrappers.isEmpty()){dispatchedtrue;for(EventSubscriberwrapper:wrappers){enqueueEvent(event,wrapper);}}}finally{subscribersByTypeLock.readLock().unlock();}}if(!dispatched!(eventinstanceofDeadEvent)){post(newDeadEvent(this,event));}dispatchQueuedEvents();}该方法就是从之前的容器subscribersByType里获取到eventType对应的观察者然后组装成EventWithSubscriber放到队列里。void enqueueEvent(Object event, EventSubscriber subscriber) {eventsToDispatch.get().offer(new EventWithSubscriber(event, subscriber));}123voidenqueueEvent(Objectevent,EventSubscribersubscriber){eventsToDispatch.get().offer(newEventWithSubscriber(event,subscriber));}然后就是最后的dispatchQueuedEvents()经过一层层深入进去可以发现wrapper.handleEvent(event)其中 handleEvent方法就是最终的关键了public void handleEvent(Object event) throws InvocationTargetException {checkNotNull(event);try {method.invoke(target, new Object[] { event });} catch (IllegalArgumentException e) {throw new Error(Method rejected target/argument: event, e);} catch (IllegalAccessException e) {throw new Error(Method became inaccessible: event, e);} catch (InvocationTargetException e) {if (e.getCause() instanceof Error) {throw (Error) e.getCause();}throw e;}}123456789101112131415publicvoidhandleEvent(Objectevent)throwsInvocationTargetException{checkNotNull(event);try{method.invoke(target,newObject[]{event});}catch(IllegalArgumentExceptione){thrownewError(Method rejected target/argument: event,e);}catch(IllegalAccessExceptione){thrownewError(Method became inaccessible: event,e);}catch(InvocationTargetExceptione){if(e.getCause()instanceofError){throw(Error)e.getCause();}throwe;}}就是通过Java的反射机制实现。需要说明的是如果没有订阅者注册到要发送的event事件上并且该event不是DeadEvent那么它将被包装成DeadEvent中并重新发布。也就是其中这三行代码索要做的if (!dispatched !(event instanceof DeadEvent)) {post(new DeadEvent(this, event));}123if(!dispatched!(eventinstanceofDeadEvent)){post(newDeadEvent(this,event));}本文系本人原创如要转载请注明出处浏览量:1410