前言
RxJava可能有些小伙伴没有听过是什么东西,可能是因为大家平时在做业务需求的时候对异步编程了解得比较少,而RxJava就是这么一个响应式编程框架,RxJava在安卓上面用得非常多,做安卓的朋友肯定对它很熟悉。那我这里为什么要讲这个呢?因为spring cloud中服务治理框架Hystrix中大量用到了RxJava的响应式编程,为了便于理解,这里也简单给大家介绍一下。这里介绍的版本是RxJava 1.X版本的, 而在去年的早些时候,官方便宣布,将在一段时间后不再对 RxJava 1.x 进行维护,推出了RxJava2.X版本,既然有新的,为什么不介绍新的呢?因为目前最新的Hystrix版本1.5.12中使用的RxJava是1.2版本的,而2.X版本的api改动还是比较大的,所以为了大家能更加简单的理解Hystrix,所以这里是对1.X版本的介绍。
响应式编程是什么
响应式编程是一种基于异步数据流概念的编程模式,有点类似于JAVA里面的lambda表达式,相信大家都很熟悉lambda吧。数据流,stream,大家肯定不陌生,我们可以对stream有很多操作,filter、map、reduce 等常见操作。然后响应式中的核心就是响应二字,响应什么呢?响应的是事件,event 。 而流就是一个按照时间进行排序的事件序列。RxJava里面的事件是基于观察者模式,事件流将从上往下,从订阅源传递到观察者。
RxJava中重要概念
RxJava 有四个基本概念:Observable
(可观察者,即被观察者)、 Observer
(观察者)、 Subscriber
(订阅,是Observer
的抽象实现类,本质上使用是一样的)、事件。Observable
和 Observer
通过 subscribe()
方法实现订阅关系,从而 Observable
可以在需要的时候发出事件来通知 Observer
。Observable
就像是一个生产者,在不断的生产消息,而Subscriber
和 Observer
就像是一个消费者,在不断的消费消息
另外, RxJava 的事件回调方法还定义了两个特殊的事件,在Hystrix中用得也非常多:onCompleted()
和 onError()
。
onCompleted()
: 事件队列完结。RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。RxJava 规定,当不会再有新的onNext()
发出时,需要触发onCompleted()
方法作为标志。onError()
: 事件队列异常。在事件处理过程中出异常时,onError()
会被触发,同时队列自动终止,不允许再有事件发出。
怎么做
说了这么多概念,估计大家都是一头雾水,我们直接来些实际的,加深大家的印象理解。用多的自然而然就会了,就懂了,这里说得可能不是最全的,但是说的都是Hystrix中用得很多的一些操作符,加深大家对Hystrix的理解,看源码就会容易一些。
例子
Observable<String> producer = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("apple");
subscriber.onNext("orange");
subscriber.onCompleted();
}
});
Subscriber<String> consumer = new Subscriber<String>() {
@Override
public void onNext(String s) {
LOG.info("我收到的水果有 = {}" , s);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
};
producer.subscribe(consumer);
先来一个简单的例子给大家直观的介绍下Observable
和 Subscriber
做了些什么,Observable
使用了onNext方法生产了2个水果,Apple和orange ,然后调用了onCompleted方法结束了这次生产, 消费者用onnext方法收到了2个水果,所以消费者就将收到的水果打印出来了,没有做任何处理
执行结果如下:
2018-04-27 10:21:11.440 INFO [#][#] <main> com.dzy.learn.other.NormalTest :我收到的水果有 = apple
2018-04-27 10:21:11.440 INFO [#][#] <main> com.dzy.learn.other.NormalTest :我收到的水果有 = orange
然后再给大家介绍一下Hystrix中用得非常多的操作符
create
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("item1");
subscriber.onNext("item2");
subscriber.onCompleted();
}
});
//在上面的例子中已经跟大家讲过了,create就是创建一个Observable,来生产消息
from
List<String> fruitList = Arrays.asList("apple","orange");
Observable.from(fruitList).subscribe(new Action1<String>() {
@Override
public void call(String fruit) {
LOG.info("fruit = {}" , fruit);
}
});
上面订阅者的代码被我简化了,直接new 一个Action1, 是subscribe支持的一种订阅方式,跟Subscriber是一样的道理,只是更加简化。然后我们再用lambda表达式简化一下就是这样的了
List<String> fruitList = Arrays.asList("apple","orange");
Observable.from(fruitList).subscribe(fruit -> LOG.info("fruit = {}" , fruit));
执行结果如下:
2018-04-27 10:30:59.030 INFO [#][#] <main> com.dzy.learn.other.NormalTest :fruid = apple
2018-04-27 10:30:59.030 INFO [#][#] <main> com.dzy.learn.other.NormalTest :fruid = orange
defer
只有当订阅者订阅才创建Observable,为每个订阅创建一个新的Observable。内部通过OnSubscribeDefer
在订阅时调用Func0创建Observable
List<String> fruitList = Arrays.asList("apple","orange");
Observable.defer(new Func0<Observable<String>>() {
@Override
public Observable<String> call() {
return Observable.from(fruitList);
}
}).subscribe(new Action1<String>() {
@Override
public void call(String fruit) {
LOG.info("defer fruit = {}" , fruit);
}
});
不知道大家理解了没有,每次生产消息都会生产一个新的消息生产者
执行结果如下:
2018-04-27 10:37:26.209 INFO [#][#] <main> com.dzy.learn.other.NormalTest :defer fruit = apple
2018-04-27 10:37:26.209 INFO [#][#] <main> com.dzy.learn.other.NormalTest :defer fruit = orange
startWith
在生产的第一个消息前加上一个或者一些消息,看例子比较直观
List<String> fruitList = Arrays.asList("apple","orange");
Observable.from(fruitList)
.startWith("before apple","before apple2")