RxJava响应式编程框架
在Spring Cloud框架中涉及的Ribbon和Hystrix两个重要的组件都使用了RxJava响应式编程框架,其作为重要的编程基础知识,特开辟一章对RxJava的使用进行详细的介绍。
Hystrix和Ribbon的代码中大量运用了RxJava的API,对于有RxJava基础的同学,学习Hystrix和Ribbon并不是一件难事。如果不懂RxJava,对于Hystrix和Ribbon的学习就会令人头疼不已。
从基础原理讲起:观察者模式
本文的重要特色,从基础原理讲起。只有了解了基础原理,大家对新的知识,特别是复杂的知识才能更加容易地理解和掌握。
RxJava是基于观察者模式实现的,这里先带领大家复习一下观察者模式的基础原理和经典实现。当然,这也是Java工程师面试必备的一个重要知识点。
观察者模式的基础原理
观察者模式是常用的设计模式之一,是所有Java工程师必须掌握的设计模式。观察者模式也叫发布订阅模式。
此模式的角色中有一个可观察的主题对象Subject,有多个观察者Observer去关注它。当Subject的状态发生变化时,会自动通知这些Observer订阅者,令Observer做出响应。
在整个观察者模式中一共有4个角色:Subject(抽象主题、抽象被观察者)、Concrete Subject(具体主题、具体被观察者)、Observer(抽象观察者)以及ConcreteObserver(具体观察者)。
观察者模式的4个角色以及它们之间的关系如图4-1所示。
图4-1 观察者模式的4个角色以及它们之间的关系
观察者模式中4个角色的介绍如下:
(1)Subject(抽象主题):Subject抽象主题的主要职责之一为维护Observer观察者对象的集合,集合里的所有观察者都订阅过该主题。Subject抽象主题负责提供一些接口,可以增加、删除和更新观察者对象。
(2)ConcreteSubject(具体主题):ConcreteSubject用于保持主题的状态,并且在主题的状态发生变化时给所有注册过的观察者发出通知。具体来说,ConcreteSubject需要调用Subject(抽象主题)基类的通知方法给所有注册过的观察者发出通知。
(3)Observer(抽象观察者):观察者的抽象类定义更新接口,使得被观察者可以在收到主题通知的时候更新自己的状态。
(4)ConcreteObserver(具体观察者):实现抽象观察者Observer所定义的更新接口,以便在收到主题的通知时完成自己状态的真正更新。
观察者模式的经典实现
首先来看Subject主题类的代码实现:它将所有订阅过自己的Observer观察者对象保存在一个集合中,然后提供一组方法完成Observer观察者的新增、删除和通知。
Subject主题类的参考代码实现如下:
package com.crazymaker.demo.observerPattern;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class Subject {
//保存订阅过自己的观察者对象
private List<Observer> observers = new ArrayList<>();
//观察者对象订阅
public void add(Observer observer) {
observers.add(observer);
log.info( "add an observer");
}
//观察者对象注销
public void remove(Observer observer) {
observers.remove(observer);
log.info( "remove an observer");
}
//通知所有注册的观察者对象
public void notifyObservers(String newState) {
for (Observer observer : observers) {
observer.update(newState);
}
}
}
接着来看ConcreteSubject具体主题类:它首先拥有一个成员用于保持主题的状态,并且在主题的状态变化时调用基类Subject(抽象主题)的通知方法给所有注册过的观察者发出通知。
package com.crazymaker.demo.observerPattern;
import lombok.extern.slf4j.Slf4j;
@Data
@Slf4jpublic class ConcreteSubject extends Subject {
private String state; //保持主题的状态
public void change(String newState) {
state = newState;
log.info( &