RxJava是响应式程序设计的一种实现。在响应式程序设计中,当数据到达的时候,消费者做出响应。响应式编程可以将事件传递给注册了的observer。今天我们就来学习一下rxJava,并分析一下它源码感受一下它的观察者模式。

RxJava的简单使用

一、mavan的pom.xml中增加rxjava的依赖

这里我们用的是rxjava1.3.0,目前最新的已经更新到2了。

<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<version>1.3.0</version>
</dependency>

二、测试的用类

import rx.Observable;
import rx.Subscriber;
/**
* @author huhx
*/
public class RxJavaTest {
public static void main(String[] args) {
Observable<String> observable = Observable.just("One", "Two", "Three");
observable.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("onCompleted");
} @Override
public void onError(Throwable item) {
System.out.println("onError");
} @Override
public void onNext(String item) {
System.out.println("Item is " + item);
}
});
}
}

三、打印的结果如下:

Item is One
Item is Two
Item is Three
onCompleted

RxJava源码的简单分析

根据上述的代码,我们简单分析一下程序的流程。

一、首先Observable.just("One", "Two", "Three")代码:

just是一个工厂方法,用心构建一个Observable对象。

public static <T> Observable<T> just(T t1, T t2, T t3) {
return from((T[])new Object[] { t1, t2, t3 });
}

from方法的代码如下:

public static <T> Observable<T> from(T[] array) {
int n = array.length;
if (n == 0) {
return empty();
} else
if (n == 1) {
return just(array[0]);
}
return unsafeCreate(new OnSubscribeFromArray<T>(array));
}

二、我们重点是看unsafeCreate方法:

public static <T> Observable<T> unsafeCreate(OnSubscribe<T> f) {
return new Observable<T>(RxJavaHooks.onCreate(f));
}

对于RxJavaHooks.onCreate()方法,第一次会先执行RxJavaHooks静态块的代码。

static {
init(); // 初始化了很多RxJavaHooks跟事件有着的变量
}

onCreate方法中,这个没有怎么看懂后续再会。

public static <T> Observable.OnSubscribe<T> onCreate(Observable.OnSubscribe<T> onSubscribe) {
Func1<Observable.OnSubscribe, Observable.OnSubscribe> f = onObservableCreate;
if (f != null) {
return f.call(onSubscribe);
}
return onSubscribe;
}

三、对于observable.subscribe()代码

public final Subscription subscribe(Subscriber<? super T> subscriber) {
return Observable.subscribe(subscriber, this);
}

Observable的subscribe方法代码如下:

 static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
if (subscriber == null) {
throw new IllegalArgumentException("subscriber can not be null");
}
if (observable.onSubscribe == null) {
throw new IllegalStateException("onSubscribe function can not be null.");
} subscriber.onStart(); if (!(subscriber instanceof SafeSubscriber)) {
subscriber = new SafeSubscriber<T>(subscriber);
} try {
RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
return RxJavaHooks.onObservableReturn(subscriber);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
if (subscriber.isUnsubscribed()) {
RxJavaHooks.onError(RxJavaHooks.onObservableError(e));
} else {
try {
subscriber.onError(RxJavaHooks.onObservableError(e));
} catch (Throwable e2) {
Exceptions.throwIfFatal(e2);
RuntimeException r = new OnErrorFailedException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
RxJavaHooks.onObservableError(r);
throw r; // NOPMD
}
}
return Subscriptions.unsubscribed();
}
}

四、整个的正常流程会走到16行的代码,这个是我们重点的分析地方。如果是异常情况,则只会执行onError方法

对于这个例子中,RxJavaHooks.onObservableStart(observable, observable.onSubscribe)得到的结果OnSubscribeFromArray这个类。调用它的call方法。

public void call(Subscriber<? super T> child) {
child.setProducer(new FromArrayProducer<T>(child, array));
}

setProducer方法执行的代码如下:

 public void setProducer(Producer p) {
long toRequest;
boolean passToSubscriber = false;
synchronized (this) {
toRequest = requested;
producer = p;
if (subscriber != null) {
// middle operator ... we pass through unless a request has been made
if (toRequest == NOT_SET) {
// we pass through to the next producer as nothing has been requested
passToSubscriber = true;
}
}
}
// do after releasing lock
if (passToSubscriber) {
subscriber.setProducer(producer);
} else {
// we execute the request with whatever has been requested (or Long.MAX_VALUE)
if (toRequest == NOT_SET) {
producer.request(Long.MAX_VALUE);
} else {
producer.request(toRequest);
}
}
}

这里会走到21行的代码,跟进去FromArrayProducer的request方法:

public void request(long n) {
if (n < 0) {
throw new IllegalArgumentException("n >= 0 required but it was " + n);
}
if (n == Long.MAX_VALUE) {
if (BackpressureUtils.getAndAddRequest(this, n) == 0) {
fastPath();
}
} else
if (n != 0) {
if (BackpressureUtils.getAndAddRequest(this, n) == 0) {
slowPath(n);
}
}
}

对于fastPath()的代码如下:

void fastPath() {
final Subscriber<? super T> child = this.child; for (T t : array) {
if (child.isUnsubscribed()) {
return;
}
child.onNext(t);
}
if (child.isUnsubscribed()) {
return;
}
child.onCompleted();
}

执行onNext()方法,其中t就是Observable.just()方法的参数。child就是observable.subscribe的定义的参数。

友情链接

java框架---->RxJava的使用(一)的更多相关文章

  1. Java 框架、库和软件的精选列表(awesome java)

    原创翻译,原始链接 本文为awesome系列中的awesome java Awesome Java Java 框架.库和软件的精选列表 项目 Bean映射 简化 bean 映射的框架 dOOv - 为 ...

  2. 如何在Eclipse中查看JDK以及JAVA框架的源码(转载)

    原文链接:http://www.cnblogs.com/outlooking/p/5243415.html 设置步骤如下: 1.点 “window”-> "Preferences&qu ...

  3. Java框架介绍-13个不容错过的框架项目

    本文转自互联网,个人收藏所用. 下面,我们将一同分享各有趣且颇为实用的Java库,大家请任取所需.不用客气~ 1.极致精简的Java Bootique是一项用于构建无容器可运行Java应用的极简技术. ...

  4. 如何查看JDK以及JAVA框架的源码

    如何查看JDK以及JAVA框架的源码 设置步骤如下: 1.点 “window”-> "Preferences" -> "Java" -> &q ...

  5. 对java框架的几点认识

    java框架实在是太多了,网上一抄一大段,根本就了解不到什么.我还是以我的经验来说一下j2ee的框架.1.首先力推struts2框架,这是最经典的框架(可以说没有“之一”).可以帮你快速搭建出一个MV ...

  6. 最简单的Java框架

    框架framework的目的是定义骨架式方案,处理各种相同的底层细节:而开发人员使用框架时,能够依照自己的需求实现自己的功能--仅仅须要填入自己的东西/flesh. 最简单的框架,类似于JUnit,它 ...

  7. 2016年7款最流行的Java框架

    虽然Java一直被唱衰,但是直到现在Java也坚持霸主地位不动摇,毫无疑问,Java是目前最热门的编程语言之一,所以我们为大家搜集了一些目前比较受欢迎的Java框架的消息. 根据RebelLabs对在 ...

  8. Java框架spring Boot学习笔记(六):Spring Boot事务管理

    SpringBoot和Java框架spring 学习笔记(十九):事务管理(注解管理)所讲的类似,使用@Transactional注解便可以轻松实现事务管理.

  9. Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)

    在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...

随机推荐

  1. [翻译] C# 8.0 新特性 Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南) 【由浅至深】redis 实现发布订阅的几种方式 .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐

    [翻译] C# 8.0 新特性 2018-11-13 17:04 by Rwing, 1179 阅读, 24 评论, 收藏, 编辑 原文: Building C# 8.0[译注:原文主标题如此,但内容 ...

  2. 如何读取xml文件,根据xml节点属性查询并输出xml文件

    主要是应用SimpleXML和递归函数来根据key值来查询,并将结果以xml格式输出. <?php header("Content-type: text/xml"); //以 ...

  3. 如何在IIS7或IIS7.5中导入导出站点及应用程序池. -摘自网络

    为实现负载平衡,我们可能会使用多个WEB服务器,也就会需要给多个IIS配置同样的站点和应用程序池.那么我们需要一个一个的重新建吗?当然不用,我们只需要一些简单的命令就可以在IIS7(Windows S ...

  4. Mysql User表权限字段说明全介绍

    一:mysql权限表user字段详解: Select_priv.确定用户是否可以通过SELECT命令选择数据. Insert_priv.确定用户是否可以通过INSERT命令插入数据. Update_p ...

  5. java后台分页实例一

    后台框架:jfinal + velocity.前台框架:jquery  页面 <!DOCTYPE html> <html> <head> <meta char ...

  6. Ubuntu14.04单机版kubernetes安装指导

    转:http://dockone.io/article/950 概述本文主要讲述如何在Ubuntu系统上安装kubernetes,网络上也有许多相关的文章,感觉都不是很清晰,这里我将自己的安装实践给大 ...

  7. matlab保存画框图像去白边

    在matlab图像处理中,为了标识出图像的目标区域来,需要利用plot函数或者rectangle函数,这样标识目标后,就保存图像. 一般saves保存的图像存在白边,可以采用imwrite对图像进行保 ...

  8. iOS应用代码段瘦身办法

    iOS应用代码段瘦身办法 大型app应对苹果官方代码段大小限制的小伎俩… 背景 苹果官方文档 对二进制 __TEXT 段大小有限制: 代码实在瘦不下去怎么办? 解决方案 利用 rename_secti ...

  9. jq判断元素class是否定义了CSS样式

    if($("div").attr("class")==null) 如果$("div").attr("class")为空, ...

  10. headfirst设计模式swift版01

    headfirst设计模式这本书真好,准备用一个月学完.书里讲得很清楚了. 设计原则: 1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起. 2.针对接口编程,而不是针 ...