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#:数学运算(待补充)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyCo ...

  2. Mysql 创建表和删除表

    在数据库中创建一张表的基本语法如下: CREATE TABLE tablename (column_name_1 column_type_1 constraints, column_name_2 co ...

  3. Redis 实现接口访问频率限制

    为什么限制访问频率 做服务接口时通常需要用到请求频率限制 Rate limiting,例如限制一个用户1分钟内最多可以范围100次 主要用来保证服务性能和保护数据安全 因为如果不进行限制,服务调用者可 ...

  4. unity,List元素第一个成员最好是string类型

    例如 List<CmyObj> m_list=new List<CmyObj>(); class CmyObj{ string m_name; int m_value; } c ...

  5. css 优先级的bug

    对于前端而言,了解css样式的优先级,对开发或处理bug有着事半功倍的效果,今天在做项目的时候,突然碰到一个优先级的小问题,刚开始不知道所因,后来才发现这个问题是由优先级造成的.先描述下问题,鼠标悬停 ...

  6. javascript 异步实现方案

    1.回调函数 fn1( fn2 ); 2.事件监听 fn1.on('done', fn2); function fn1() { setTimeout(function(){ fn1.trigger(' ...

  7. 一款基于jQuery的全屏广告图片焦点图

    之前为大家分享了很多jQuery焦点图插件.今天我们要介绍的这款jQuery全屏广告图片焦点图插件也非常不错,图片切换时有淡出淡出的动画效果,并且也相当流畅.效果图如下: 在线预览   源码下载 实现 ...

  8. Javascript知识点:IIFE - 立即调用函数

    Immediately-invoked Function Expression(IIFE,立即调用函数),简单的理解就是定义完成函数之后立即执行.因此有时候也会被称为“自执行的匿名函数”(self-e ...

  9. kickstart安装步骤

    1.1 环境说明 [root@test ~]# cat /etc/redhat-release CentOS release 6.9 (Final) [root@test ~]# uname -r 2 ...

  10. Istio微服务架构初试

    感谢 http://blog.csdn.net/qq_34463875/article/details/77866072 看了一些文档,有些半懂不懂,所以还是需要helloworld一下.因为isti ...