编写不易,转载请注明(http://shihlei.iteye.com/blog/2426888)!
一 概述
最近看RxJava,其骨架就是使用的观察者模式,所以对观察者模式做个总结,顺便记录一下Guava EventBus的实现(事件监听,其实也相当于观察者模式)
二 观察者模式
1)概述
观察者模式:行为模式,提供一种一对多关系绑定对象的方法,一个对象状态需发生改变,绑定对象能收到通知完成自己的业务更新。
主要成员:
被观察者(Observerable):状态变化,通知所有的观察者。
观察者(observer):接收到“被观察者”的状态变化通知,执行自己的业务。
使用场景:
“被观察者”的状态变化需要通知多个“观察者”,但“被观察者”不需要知道观察者的个数具体细节,他们之间互相独立。一般“观察者”之间相互独立,不会彼此影响。
2)Demo
package x.rx.observer; import java.util.LinkedList; import java.util.List; /** * 观察者模式: * 1)被观察者(Observerable):维护一个观察者队列,事件产生时,回调所以的观察者 * 2)观察者(Observer):注册到"被观察者"中,接收通知,执行自己的业务 * * @author shilei */ public class ObserverPatternDemo { public static void main(String[] args) { Observerable observerable = new Observerable(); observerable.register(() -> { System.out.println("observer1 handle finish!"); }).register(() -> { System.out.println("observer2 handle finish!"); }); observerable.generateEvent(); } /** * 观察者 */ interface Observer { void doEvent(); } /** * 被观察者 */ static class Observerable { private List<Observer> observerList = new LinkedList<>(); /** * 注册观察者 * * @param observer 观察者 */ Observerable register(Observer observer) { observerList.add(observer); return this; } /** * 取消注册 */ Observerable unRegister(Observer observer) { observerList.remove(observer); return this; } /** * 产生事件 */ void generateEvent() { for (Observer observer : observerList) { observer.doEvent(); } } } }
三 Guava EventBus
1) 概述
Guava EventBus 实现了事件监听器模式,主要提供一套基于注解的事件总线,可以灵活的使用。
使用方式:
1)定义一个关注的Event
2)定义一个监听处理方法,@Subscribe 标记,里面实现业务逻辑
3)注册到EventBus即可
2)Demo
(1)依赖
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency>
(2)代码
package x.rx.eventbus; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; /** * guava eventbus * * @author shilei */ public class EventBusDemo { public static void main(String[] args) { EventBus eventBus = new EventBus("demo"); // 注册 eventBus.register(new EventListener()); // 产生事件 eventBus.post(new Event()); } /** * 事件 */ static class Event { } /** * 事件监听器 */ static class EventListener { @Subscribe //这里标记这个方法是事件处理方法 public void handle1(Event event) { System.out.println("handle1 finish! "); } @Subscribe public void handle2(Event event) { System.out.println("handle2 finish! "); } } }
3)源码分析
(1)事件注册到总线:EventBus的register()
private final SubscriberRegistry subscribers = new SubscriberRegistry(this); /** * Registers all subscriber methods on {@code object} to receive events. * * @param object object whose subscriber methods should be registered. */ public void register(Object object) { subscribers.register(object); }
“被观察者”的核心,提供一个队列,维护所有需要通知的观察者,Guava EventBus 这个工作代理给了 SubscriberRegistry , SubscriberRegistry 提供任何类型的事件到事件处理类的绑定关系。
看看注册的细节:
/** * All registered subscribers, indexed by event type. * * <p>The {@link CopyOnWriteArraySet} values make it easy and relatively lightweight to get an * immutable snapshot of all current subscribers to an event without any locking. */ private final ConcurrentMap<Class<?>, CopyOnWriteArraySet<Subscriber>> subscribers = Maps.newConcurrentMap(); /** * Registers all subscriber methods on the given listener object. */ void register(Object listener) { Multimap<Class<?>, Subscriber> listenerMethods = findAllSubscribers(listener); for (Map.Entry<Class<?>, Collection<Subscriber>> entry : listenerMethods.asMap().entrySet()) { Class<?> eventType = entry.getKey(); Collection<Subscriber> eventMethodsInListener = entry.getValue(); CopyOnWriteArraySet<Subscriber> eventSubscribers = subscribers.get(eventType); if (eventSubscribers == null) { CopyOnWriteArraySet<Subscriber> newSet = new CopyOnWriteArraySet<Subscriber>(); eventSubscribers = MoreObjects.firstNonNull(subscribers.putIfAbsent(eventType, newSet), newSet); } eventSubscribers.addAll(eventMethodsInListener); } }
内部是一个ConcrurentMap,key 是事件class,value是个 CopyOnWriteArraySet<Subscriber> 用于通知,最重要的方法 findAllSubscribers(listener) ,他会通过反射,找到 @Subscribe 注解的方法,并关联他绑定的事件。获取到就添加到 subscribers(类型ConcrurentMap)中,这个subscribers 维护了所有的事件和事件处理器的绑定关系。
看看findAllSubscribers(listener) 的细节:
/** * Returns all subscribers for the given listener grouped by the type of event they subscribe to. */ private Multimap<Class<?>, Subscriber> findAllSubscribers(Object listener) { Multimap<Class<?>, Subscriber> methodsInListener = HashMultimap.create(); Class<?> clazz = listener.getClass(); for (Method method : getAnnotatedMethods(clazz)) { Class<?>[] parameterTypes = method.getParameterTypes(); Class<?> eventType = parameterTypes[0]; methodsInListener.put(eventType, Subscriber.create(bus, listener, method)); } return methodsInListener; }
相关推荐
Guava的EventBus是观察者模式的一个实例,它简化了事件发布和订阅的过程。EventBus允许你定义事件的发布者(即被观察者)和事件的订阅者(即观察者)。发布者通过调用EventBus的post方法发布事件,而订阅者通过在...
9. **扩展**:除了Java内置的`Observer`和`Observable`,开发者还可以使用第三方库如Guava的`EventBus`,或者Spring框架的`ApplicationEvent`和`ApplicationListener`,这些都提供了更高级的观察者模式实现。...
它基于观察者模式(或发布订阅模式),主要分为三部分:发布者、监听者、事件。EventBus的使用非常简单,只需要定义事件对象、事件监听器和事件发布者。 在上面的代码示例中,我们定义了一个HelloEvent事件对象和一...
发布-订阅(观察者)模式是软件设计模式中的一种行为模式,它在Java中得到了广泛的应用。这种模式的核心思想是定义对象之间的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在...
EventBus是一种观察者模式的实现,它允许组件之间通过发布和订阅事件进行通信,而不必显式地相互依赖。通过注册到EventBus的订阅者可以接收特定类型的事件,而发布者只需发送事件,无需关心哪个或哪些订阅者会处理...
EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。 ...
EventBus是Google Guava库的一部分,它提供了一种发布/订阅模式的事件传递机制,允许应用程序的不同组件之间进行异步通信,而无需直接引用彼此。 **二、EventBus的使用** 1. **依赖添加**:首先,在SpringBoot项目...
在异步非阻塞的EventBus框架中,观察者模式是核心机制,它允许订阅者注册事件监听,并在事件触发时进行相应处理。 6. 访问者模式:访问者模式是一种行为设计模式,它允许在不修改类结构的情况下,向已存在的对象...
在Java中,除了标准库提供的Observable和Observer之外,还可以使用第三方库如Guava的EventBus或Spring框架的ApplicationEventPublisher接口来实现观察者模式,这些库提供了更高级的功能和更好的扩展性。 总之,...
RxJava是一个强大的异步编程库,它将观察者模式和函数响应式编程结合在一起。RxBus使用`Observable`来发布事件,订阅者通过`subscribe()`方法订阅这些事件。RxBus的优势在于它可以提供更复杂的事件传播规则,如延迟...
10. **设计模式**:Java开发者应该熟悉GOF(Gang of Four)设计模式,包括工厂模式、观察者模式、装饰器模式等,它们是解决常见软件设计问题的有效工具。 在构建类似Prism的Java框架时,上述知识点将构成核心组件,...
观察者模式和事件总线(如Guava的EventBus或Kotlin的Coroutines Channel)是实现事件驱动编程的常见工具。 9. **测试与调试**:单元测试、集成测试和端到端测试是确保代码质量的关键步骤。JUnit、Mockito等库可以...