RxJava源码笔记(一)

本文详细介绍了RxJava框架的基础概念,包括被观察者、观察者、事件和订阅流程。通过分析源码,展示了从创建数据流到订阅过程中的 observable 生成和回溯机制,以及数据如何从上游通过下游的 observer 处理。最后,作者预告了接下来会探讨RxJava的线程切换调度、背压和常见操作符的源码分析。
摘要由CSDN通过智能技术生成

更多看这里吧😁

RxJava源码笔记(一)

前言

​ RxJava框架能简单高效地构建异步流,但是使用门槛较高。Java中实现异步的方式有很多,比如Thread类、Runnable以及Callable接口。但是他们直接使用起来相对没那么优雅,JDK1.5之前使用的Future类,以及之后的CompletableFuture类对异步任务的构建进行了优化。

​ RxJava框架在很多地方都有涉及,比如Netflix的Hystrix的框架,CouchBase的Java SDK,Vertx框架的构建异步任务也常用RxJava来优化避免回调地狱。

RxJava简介

名词解释

​ 第一次听到这个名字的时候把RxJava听成了Ajax😅

​ R=Reactive x=Extensions Rx的意思是为了异步编程而做的响应式扩展(Reactive Extensions for Async Programming)。就是方便用户进行响应式的异步编程而创造的第三方库。因此Rx在很多语言上都有实现,比如js上实现的rxjs,基于Kotlin语言的RxKotlin,以及基于Java JVM实现的RxJava(笔记基于RxJava 2.x的版本)。

概念解释

​ RxJava基于观察者模式,存在如下几种角色

角色角色功能
被观察者(Observable产生事件
观察者(Observer响应事件并做出处理
事件(Event被观察者和观察者的消息载体
订阅(Subscribe连接被观察者和观察者

​ RxJava中的事件(Event)存在如下几种情况

事件类型含义说明
onNext常规事件被观察者可以发送无数个Next事件,观察者也可以接受无数个Next事件
onComplete结束事件被观察者发送Complete事件后可以继续发送事件,观察者收到Complete事件后将不会接受其他任何事件
onError异常事件被观察者发送Error事件后,其他事件将被终止发送,观察者收到Error事件后将不会接受其他任何事件

其中onComplete和onError之间是互斥的,一个发生了另一个就不会发生。

基本流程

比较核心的部分是订阅流程线程切换流程

订阅流程

下行

订阅(Subcribe)前需要构建数据流

// 利用create操作符创建一个被观察者(observable), observable0
Observable<String> observable0 = Observable.create(new ObservableOnSubscribe<String>() {
    	   // 1.
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                // onNext设置每次向下游发射的数据
                emitter.onNext("1");
                emitter.onNext("2");
                emitter.onNext("3");
            }
        });

// 利用map操作符在上游被观察者observable0上继续创建一个被观察者observable1
// map操作符表示对上游每一个onNext发射的数据("1","2","3")进行映射(apply方法)得到一个新的数据,构建新的流发射给下游
// 2.
Observable<String> observable1 = observable0.map(new Function<String, String>() {
            @Override
            public String apply(String s) throws Exception {
                return s + "#";
            }
        });

// 同上map方法……
Observable<String> observable2 = observable1.map(new Function<String, String>() {
            @Override
            public String apply(String s) throws Exception {
                return s + "*";
            }
        });
// 生成下游观察者observer,设置onNext, onError, onComplete等回调方法,
Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                // 当出发subscribe方法时候触发
                System.out.println("onSubscribe");
            }

            @Override
            public void onNext(String s) {
                // 当上游observable1每次发射数据时候触发
                System.out.println("onNext : " + s);
            }

            @Override
            public void onError(Throwable e) {
                // 当上游observable1每次发射数据异常时候触发(最多触发一次)
                System.out.println("onError : " + e.toString());
            }

            @Override
            public void onComplete() {
                // 当上游observable1显示调用onComplete方法时候触发(最多触发一次),否则不触发
                System.out.println("onComplete");
            }
        };
// 订阅observable2上游的数据流,响应上游每次发射的数据的事件
// 3.
 observable2.subscribe(observer);

得到的结果是

onSubscribe
onNext : 1#*
onNext : 2#*
onNext : 3#*

接下来开始分析基本构建流程:

从1.处的Observable.create方法开始

Observable#create

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    	// 判空,对阅读没啥帮助,不用看
        ObjectHelper.requireNonNull(source, "source is null"); 
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }

创建了一个ObservableCreate对象,这玩意看看是啥,

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        // new ObservableCreate<T>(source)时候将被观察者source传入,并设置为属性
        this.source = source;
    }
	
    // 关键方法
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
       // 先省略
    }

    static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {
       // 先省略
    }
    // 忽略其他次要的代码……
}

原来ObservableCreate也是一个被观察者Observable,继承了Observable。

将这个ObservableCreate传入RxJavaPlugins.onAssembly,看看这个方法干了啥

// 设置钩子方法,默认null不设置,可以手动设置它去记录日志之类的
static volatile Function<? super Observable, ? extends Observable> onObservableAssembly;

// Calls the associated hook function.
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        // 默认这里不执行,直接返回source
    	if (f != null) {
            return apply(f, source);
        }
        return source;
    }

配合注释发现没软用,这个方法啥都没干,将source原封不动返回了。

以上就是create方法在构建流中起到的功能:返回一个新的被观察者Observable, 并且设置我们自定义的source(ObservableOnSubscribe)作为成员变量。

接下来看看构建流的下一步,从2.处的observabl0.map方法开始

Observable#map

public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
       // 判空,不看
        ObjectHelper.requireNonNull(mapper, "mapper is null");
       // 同样的RxJavaPlugins.onAssembly啥都没干,下面等价于: 
       // return new ObservableMap<T, R>(this, mapper);
        return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
    }

创建了一个ObservableMap对象,这玩意看看是啥,

public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    final Function<? super T, ? extends U> function;

    public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
        // 构造方法:同时将上游的observable0对象作为source参数,对每个元素的映射关系的function作为参数传入。
        // 也就意味着下游observable会拥有上游observable的引用,方便后续订阅时候调用上游的subscribe()
        super(source);
        this.function = function;
    }
	
    // 关键方法
    @Override
    public void subscribeActual(Observer<? super U> t) {
        // 方便后续订阅时候调用
        source.subscribe(new MapObserver<T, U>(t, function));
    }

    static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
        final Function<? super T, ? extends U> mapper;

        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
            super(actual);
            this.mapper = mapper;
        }
        // 忽略其他次要的代码……
    }
abstract class AbstractObservableWithUpstream<T, U> extends Observable<U> implements HasUpstreamObservableSource<T> 

ObservableMap继承自 AbstractObservableWithUpstream, AbstractObservableWithUpstream继承自Observable。所以ObservableMap也是一个被观察者Observable。

以上就是map方法在构建流中的功能:也是返回一个新的被观察者Observable。通过new ObservableMap<T, R>(this, mapper)可以看出,将上游(observable0)的Observable作为新的Observable的成员变量。

​ 以此类推每次map或者flatMap等操作符运算都会构建一个新的Observable对象返回给下游。observable2的的构建和observable一样,这就就不写了。

obvservable2
obvservable1
obvservable0

​ 包含关系图

以上是构建流之后的三个observable包含关系,可以看出,observable2包含了observable1,observable1包含了observable0。因此在后期订阅(subscribe方法)的时候,流可以从由外向里(由下游到上游)逐层调用对应的subscribe方法。

回溯

当触发3. observable2.subscribe时候将进行回溯,回溯的本质是将下游的订阅信息(observer观察者)回溯到上游observable中去,让最上游的observable0接收到订阅消息后将调用emitter.onNext方法依次将数据再由上向下observable0.onNext -> observable1.onNext -> observable2.onNext传递。

回溯流向
最下游observer
observable1.subscribe->observer
observable0.subscribe->observer
observable2
最下游observer
observable1
observable0

​ 回溯流向图

从代码角度来看:observable2.subscribe将下游的观察者(observer)传入

public final void subscribe(Observer<? super T> observer) {
      // 将下游观察者observer传给subscribeActual方法
      /**
      这里的最下游观察者是这一坨
      Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                // 当出发subscribe方法时候触发
                System.out.println("onSubscribe");
            }

            @Override
            public void onNext(String s) {
                // 当上游observable1每次发射数据时候触发
                System.out.println("onNext : " + s);
            }

            @Override
            public void onError(Throwable e) {
                // 当上游observable1每次发射数据异常时候触发(最多触发一次)
                System.out.println("onError : " + e.toString());
            }

            @Override
            public void onComplete() {
                // 当上游observable1显示调用onComplete方法时候触发(最多触发一次),否则不触发
                System.out.println("onComplete");
            }
        };
      **/
      subscribeActual(observer);
      // 省略其他无关代码
        }
    }

查看subscribeActual方法,发现是一个抽象方法,那么具体的实现在子类

protected abstract void subscribeActual(Observer<? super T> observer);

debug之后发现实现类是在ObservableMap类中的subscribeActual方法

	@Override
    public void subscribeActual(Observer<? super U> t) {
        source.subscribe(new MapObserver<T, U>(t, function));
    }

ObservableMap这个类似曾相识,在哪见过呢?原来在生成observable2的时候,observable1.map的时候创建的

new ObservableMap<T, R>(this, mapper);

public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
 	   // ……
       // 生成observable2
        return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
    }

所以就是observable2的subscribeActual方法。

subscribeActual方法传入了一个MapObserver对象,同时往该对象里传入下游观察者的observer和observable2内部的function。

再看看MapObserver类,他是ObservableMap(Observable)的内部类,也就是说一个Observable内往往也包含了对应观察者(observer)的内部类。

public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {

static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
        final Function<? super T, ? extends U> mapper;

        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
            // 设置下游observer为父类AbstractObservableWithUpstream中名字为downstream的变量
            super(actual);
            this.mapper = mapper;
        }

        @Override
        public void onNext(T t) {
            U v;
            // 将上游发射的t数据通过observable1的map方法进行映射映射,并调用下游downstream(是一个observable)的onNext方法向下游传递
            v = mapper.apply(t);
            downstream.onNext(v);
        }
}

就这样返回了一个拥有onNext等方法的观察者observer。

在 observable2的subscribeActual方法中调用source.subscribe(observer); 从前面的包含关系图中可以看出这里的source应该是observable1(同样地observable1中的source也应该是observable0)。因此在observable2中调用了observable1的subscribe方法并将observable2中生成的观察者作为参数向上传递。

​ 现在到了observable1的subscribe方法,同样地,和observable2的subscribe方法一样,observable1先会在subscribe中调用subscribeActual方法,然后会到observable1具体子类ObservableMap调用subscribeActual方法,同样再new MapObserver<T, U>(t, function)返回一个observer1,再通过source的subscribe方法将observable1中生成的观察者observer1传回给observable0。

​ 接下来到了observable0的subscribe方法, 到具体实现类ObservableCreate调用subscribeActual方法

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
    
        // 这里的observer是下游传递上来的observer1
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
 		/**
 		这里的source是一开始crete里面的
        new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("1");
                emitter.onNext("2");
                emitter.onNext("3");
            }
        }
        **/
        source.subscribe(parent);
    }

    static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {

        private static final long serialVersionUID = -3434801548987643227L;

        final Observer<? super T> observer;

        CreateEmitter(Observer<? super T> observer) {
            this.observer = observer;
        }

        @Override
        public void onNext(T t) {
          // 相当于调用了ObservableEmitter的onNext方法。
          observer.onNext(t);
    }
	// ……
}

subscribeActual里调用了source.subscribe方法,这里的source就是我们一开始create方法里的lambda参数。此时subscribe来到了

emitter.onNext(“1”);这里的emitter就是现在ObservableCreate中的内部类CreateEmitter,所以相当于调用了ObservableEmitter的onNext方法。

 @Override
        public void onNext(T t) {
          // 相当于调用了ObservableEmitter的onNext方法。
          observer.onNext(t);
    }
下行流动

​ onNext中调用了从最下游来到最上游的observer的onNext方法。

此时数据开始流动:

下行流动
onNext->data
onNext->data
onNext->data
map
emitter
map
最终observer

下行流动才是真正数据开始处理的时机,体现了流惰性处理的特性。

小结

笔记(一)中介绍了RxJava的基本概念,背景等,以及订阅的基本流程。

订阅的基本流程分为3个阶段

  1. 下行:基于操作符(map, create等)向下构建流,本质是向下游传递observable被观察者对象。
  2. 回溯:当发生订阅的时候触发,本质是向上游传递observer观察者对象。
  3. 下行流动:这是真正触发运算的时机,本质是向下游传递并处理数据。上游通过observer的onNext事件将数据向下流转运算得到最终结果。

未来计划

​接下来的笔记写点RxJava线程切换调度的源码,背压以及常见操作符比如flatMap, map,take、zip的源码。

更多看这里吧😁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值