java eventbus 原理_EventBus原理解析

java eventbus 原理_EventBus原理解析前言EventBus的核心思想是观察者模式(生产/消费者编程模型)。通过前面的文章我们已经知道,如何使用eventBus了。我们需要先定义一个Observer(前文中的EventListener类),然后将其注册到eventBus里,通过@Subscribe定义消息回调函数。那我们先看看register(Objectobject)和unregister(Objectobject)方…

前言

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();

}

}

1

2

3

4

5

6

7

8

9

10

publicvoidregister(Objectobject){

Multimap,EventSubscriber>methodsInListener=

finder.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;

}

1

2

3

4

5

6

7

8

9

10

11

publicMultimap,EventSubscriber>findAllSubscribers(Objectlistener){

Multimap,EventSubscriber>methodsInListener=HashMultimap.create();

Class>clazz=listener.getClass();

for(Methodmethod:getAnnotatedMethods(clazz)){

Class>[]parameterTypes=method.getParameterTypes();

Class>eventType=parameterTypes[0];

EventSubscribersubscriber=makeSubscriber(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();

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

publicvoidunregister(Objectobject){

Multimap,EventSubscriber>methodsInListener=finder.findAllSubscribers(object);

for(Entry,Collection>entry:

methodsInListener.asMap().entrySet()){

Class>eventType=entry.getKey();

CollectioneventMethodsInListener=entry.getValue();

subscribersByTypeLock.writeLock().lock();

try{

SetcurrentSubscribers=subscribersByType.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();

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

publicvoidpost(Objectevent){

Set>dispatchTypes=flattenHierarchy(event.getClass());

booleandispatched=false;

for(Class>eventType:dispatchTypes){

subscribersByTypeLock.readLock().lock();

try{

Setwrappers=subscribersByType.get(eventType);

if(!wrappers.isEmpty()){

dispatched=true;

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));

}

1

2

3

voidenqueueEvent(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;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

publicvoidhandleEvent(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));

}

1

2

3

if(!dispatched&&!(eventinstanceofDeadEvent)){

post(newDeadEvent(this,event));

}

本文系本人原创,如要转载,请注明出处!

浏览量:

141

0

今天的文章java eventbus 原理_EventBus原理解析分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/6591.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注