1. 简介
观察者模式,也叫发布-订阅模式, 定义了一对多的依赖关系. 多个观察者监听一个主题.
主题发生变化时, 观察者得到通知, 然后选择后续的动作.
这里的得到通知, 根据是主题主动通知还是观察者主动请求分为推模型和拉模型
类图如下:
上图是观察者模式的最简单实现,类似于OS中的最小系统. 和一般面向对象语言的设计模式一样, 都会使用到多态, 利于程序的可扩展性.类图中分为4个角色:
抽象主题: Subject
具体主题: ConcreteSubject
抽象观察者: Observer
具体观察者: ConcreteObserver
观察者只有一个方法update(). 主题Subject中, 有3个方法 add() 或 register(), remove(), notify().
最主要的是notify(), 一般是主题遍历自己维护的观察者队列中的所有观察者, 一次调用观察者的update().
这里有一个思维的误区, 观察者收到通知,然后自己选择是否进行操作. 实际上是一个被动的过程.
首先观察者将自己注册到主题中, 主题维护一个队列,用于持有该观察者的引用. 之后由主题调用观察者的方法进行更新.
2. tomcat中的应用
这里借用网络上的一个例子.
tomcat中,定义了一个LifeCycleSupport类, 协助管理观察者, 其实也是对观察者模式的一个延伸.
fireLifeCycleEvent里面有一个fireLifeCycleEvent()方法,也就是类图中的notify().
public void fireLifeCycleEvent (String type, Object data) { LifeCycleEvent event = new LifeCycleEvent(lifecycle, type, data); LifeCycleListener linterested = listeners; for (int i = 0; i < interested.length; i++) { interested[i].llfecycleEvent(event); }
参数中的LifecycleEvent 是tomcat定义的事件, 如下:
public LifecycleEvent (Lifecycle lifecycle, String type, Object data) { super(lifecycle); this.type = type; this.data = data; }
从上可知,tomcat中观察者的流程如下:
1. 将观察者listener加到LifeCycleSupport的listener数组中
2. 主题做某些动作时, 生成一个LifeCycleEvent对象, 标明这是一个什么样的事件. 之后由LifeCycleSupport通知listener中的每一个观察者,
3. listener会根据事件的类型, 做出对应的动作
3. 观察者应用的场景
观察者适用于几个场景
①一个对象的改变需要通知到多个对象. 但是又不清楚具体有多少个对象需要通知,.
观察者使用了集合 + 接口实线了解耦, 使Subject和Observer都只知道对方是一个接口, 不用关心具体的子类
②多级联动关系, 比如GUI编程中. panet A 中有多个panet B , 当panet A 需要改变时, panet B 大小也需要随着改变, 整体全部变化
③ 消息分发场景, 比如QQ广播, 新闻推送. 当然这些功能并非一定依靠观察者才能实现
4. Guava中的实现
guava中的观察者非常简单. 只需要在指定的方法加上注解 @Subscribe即可.
public class Event { @Subscribe public void sub(String msg) { //some statement System.out.println("sub method is called." + msg); } } public class Client { public static void main(String[] args) { EventBus eventbus = new EventBus(); eventbus.register(new Event()); eventbus.post("Guava EventBus is post"); //触发事件 } }
EventBus的大体实现逻辑
调用eventbus.register()时, eventbus实例会将事件对象放到SetMultimap<Class<?>, EventSubscriber> 中, 这是一个线程安全的容器, unregister()方法也在其中
再说eventbus.post()方法. eventbus实例将参数匹配的对象放到事件队列 ThreadLocal<Queue<EventWithHandler>> eventsToDispatch中, 等待事件分发完成. 再做统一的事件消费.
这里所有的容器都是线程安全的, 本地线程, 同步, 同时使用ReentranceLock.
另外EventBus提供了一个异步容器 AsyncEventBus, 示例代码如下:
public void asyncEventBus() { AsyncEventBus eventbus = new AsyncEventBus(Executor.newFixedThreadPool()); eventbus.register(new Event()); eventbus.post("async event bus called"); }
AsyncEventBus实线逻辑中, 事件注册, 移除, 和同步的EventBus是相同的逻辑, 不同的是事件的分发和消费.它的事件消费,不再使用ThreadLocal, 而是换成了ConcurrentLinkedQueue<EventWithHandler> eventsToDispatch. 消费事件任务是一个线程池, 一个Executor的实现, 这个实现需要开发自己定义.
最后是deadEvent, 使用场景如下:
public static void main(String[] args) { EventBus eventbus = new EventBus(); eventbus.register(new Event()); eventbus.post(123); //这里应该是使用String对象作为参数,但这里参数类型是int }
这里@Subscribe方法的参数类型是String, 但是@post中的参数类型是int, 导致@Subscribe方法无法被消费, EventBus会将此事件当做一个deadEvent.
相关推荐
在Java中,Guava和Spring框架都提供了实现观察者模式的工具。 Guava的EventBus是观察者模式的一个实例,它简化了事件发布和订阅的过程。EventBus允许你定义事件的发布者(即被观察者)和事件的订阅者(即观察者)。...
jar包,亲测可用
EventBus 是一个基于事件的一个发布/订阅框架,通过解耦发布者和订阅者简化事件传递,这里的事件可以理解为消息,本文中统一称为事件也就是 Event。通过EventBus可以简化生产者/消费者 这种模型,同时又可以通过...
9. **扩展**:除了Java内置的`Observer`和`Observable`,开发者还可以使用第三方库如Guava的`EventBus`,或者Spring框架的`ApplicationEvent`和`ApplicationListener`,这些都提供了更高级的观察者模式实现。...
eventBus android 跨页面异步传输数据 可用于异步网络请求和 异步跨页面传数据
EventBus和Spring Event都是基于事件机制的异步处理方式,但它们有着不同的设计理念和实现方式。在本文中,我们将详细剖析EventBus和Spring Event的区别,帮助读者更好地理解和选择合适的事件机制。 EventBus事件...
在实际应用中,Java的发布-订阅模式不仅限于`Observable`和`Observer`,还可以结合`EventBus`库如`Guava EventBus`或`Otto`等,它们提供了更强大和灵活的事件传递机制。这些库允许异步事件处理,支持事件分发的过滤...
├─Google Guava 第13讲-Guava之CharStreams和ByteStreams源码剖析(比较简单).wmv ├─Google Guava 第14讲-Guava之Closer使用和原理剖析,非常重要.wmv ├─Google Guava 第15讲-Base64原理详解,手动实现base...
SNAPSHOTMaven依赖<dependency><groupId>com.woter.fact</groupId><artifactId>fact-bus</artifactId><version>1.0.0-SNAPSHOT</version></dependency>功能描述fact-bus 是基于guava整合spring实现EventBus;...
在本文中,我们将深入探讨如何在SpringBoot应用中使用EventBus,这是一个基于Guava库的事件总线系统。EventBus的引入使得松耦合的组件间通信变得更加简单和高效。让我们一起通过步骤来理解这个“SpringBoot+EventBus...
8. **事件监听**:Guava的EventBus可以方便地实现发布/订阅模式,简化事件驱动的编程。 9. **枚举集与常量**:Guava提供了ImmutableEnumSet和ImmutableSet.of()等方法,创建不可变且高效的枚举集合。 `guava-18.0-...
jar包,亲测可用
在 Guava EventBus 的使用中,`@Subscribe` 注解是核心概念,它标记了那些监听并处理事件的方法。然而,为了保证 EventBus 的正确使用,开发者需要注意`@Subscribe` 注解的方法应遵循一定的规范,比如方法参数的数量...
EventBus是一种观察者模式的实现,它允许组件之间通过发布和订阅事件进行通信,而不必显式地相互依赖。通过注册到EventBus的订阅者可以接收特定类型的事件,而发布者只需发送事件,无需关心哪个或哪些订阅者会处理...
EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。 ...
4. **并发支持**:Guava提供了更高级的并发工具,如RateLimiter(限流器)、Service(服务管理)和ListenableFuture(监听型未来)等,使得在多线程环境中编写高效、安全的代码变得更加简单。 5. **字符串处理**:...
Guava中的原子类如AtomicInteger、AtomicLong等,以及WeakReference、SoftReference等内存管理工具,帮助开发者实现线程安全的数据结构和高效内存管理。 八、其他特性 Guava还包含了一些其他实用功能,如事件总线...
综上所述,Google Guava的定时缓存功能使得我们能够轻松地在Java应用中实现高效的缓存机制,有效减少计算和网络请求的负担,提升整体性能。通过灵活的配置和丰富的API,我们可以根据具体需求定制合适的缓存策略。在...
针对Android平台,"Node.js-EventBus简单使用实例学习使用开源库提高开发效率与速度"这个主题聚焦于如何利用EventBus库来实现这一目标。EventBus是一种发布/订阅事件总线,它简化了组件之间的通信,使得Android应用...
通过深入研究 "guava-master" 文件中的源代码,可以了解到 Guava 的具体实现细节,这对于理解和优化自己的 Java 项目非常有益。此外,了解并掌握 Guava 的使用,能够使你的代码更加简洁、高效,同时减少潜在的错误。