Hello World!
以下是HystrixCommand的基本“Hello World”实现:
public class CommandHelloWorld extends HystrixCommand<String> {
private final String name;
public CommandHelloWorld(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected String run() {
// a real example would do work like a network call here
return "Hello " + name + "!";
}
}
HystrixObservableCommand
Equivalent
使用HystrixObservableCommand而不是HystrixCommand的等效Hello World解决方案将涉及重写构造方法,如下所示:
public class CommandHelloWorld extends HystrixObservableCommand<String> {
private final String name;
public CommandHelloWorld(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected Observable<String> construct() {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> observer) {
try {
if (!observer.isUnsubscribed()) {
// a real example would do work like a network call here
observer.onNext("Hello");
observer.onNext(name + "!");
observer.onCompleted();
}
} catch (Exception e) {
observer.onError(e);
}
}
} ).subscribeOn(Schedulers.io());
}
}
Synchronous Execution
您可以与execute()方法同步执行HystrixCommand,如下例所示:
String s = new CommandHelloWorld("World").execute();
执行此表单通过以下测试:
@Test
public void testSynchronous() {
assertEquals("Hello World!", new CommandHelloWorld("World").execute());
assertEquals("Hello Bob!", new CommandHelloWorld("Bob").execute());
}
HystrixObservableCommand
Equivalent
对于HystrixObservableCommand没有简单的等效执行,但是如果您知道由这样的命令生成的Observable必须始终只生成一个值,则可以通过应用.toBlocking()。toFuture()来模仿执行行为到Observable。
Asynchronous Execution
您可以使用queue()方法异步执行HystrixCommand,如下例所示:
Future<String> fs = new CommandHelloWorld("World").queue();
您可以使用Future检索命令的结果:
String s = fs.get();
以下单元测试演示了行为:
@Test
public void testAsynchronous1() throws Exception {
assertEquals("Hello World!", new CommandHelloWorld("World").queue().get());
assertEquals("Hello Bob!", new CommandHelloWorld("Bob").queue().get());
}
@Test
public void testAsynchronous2() throws Exception {
Future<String> fWorld = new CommandHelloWorld("World").queue();
Future<String> fBob = new CommandHelloWorld("Bob").queue();
assertEquals("Hello World!", fWorld.get());
assertEquals("Hello Bob!", fBob.get());
}
以下是彼此相同的:
String s1 = new CommandHelloWorld("World").execute();
String s2 = new CommandHelloWorld("World").queue().get();
HystrixObservableCommand
Equivalent
对于HystrixObservableCommand没有简单的等效队列,但是如果您知道由此类命令生成的Observable必须始终只生成一个值,则可以通过应用RxJava运算符来模仿队列的行为.toBlocking().toFuture()到Observable。
Reactive Execution
您还可以使用以下方法之一将HystrixCommand的结果作为Observable进行观察:
- observe() - 返回一个立即执行命令的“热”Observable,但是因为Observable是通过ReplaySubject过滤的,所以在你有机会订阅之前你不会丢失它发出的任何项目
- toObservable() - 返回一个“冷”Observable,它不会执行命令并开始发出结果,直到您订阅Observable。
Observable<String> ho = new CommandHelloWorld("World").observe();
// or Observable<String> co = new CommandHelloWorld("World").toObservable();
然后,通过订阅Observable来检索命令的值:
ho.subscribe(new Action1<String>() {
@Override
public void call(String s) {
// value emitted here
}
});
以下单元测试演示了行为:
@Test
public void testObservable() throws Exception {
Observable<String> fWorld = new CommandHelloWorld("World").observe();
Observable<String> fBob = new CommandHelloWorld("Bob").observe();
// blocking
assertEquals("Hello World!", fWorld.toBlockingObservable().single());
assertEquals("Hello Bob!", fBob.toBlockingObservable().single());
// non-blocking
// - this is a verbose anonymous inner-class approach and doesn't do assertions
fWorld.subscribe(new Observer<String>() {
@Override
public void onCompleted() {
// nothing needed here
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onNext(String v) {
System.out.println("onNext: " + v);
}
});
// non-blocking
// - also verbose anonymous inner-class
// - ignore errors and onCompleted signal
fBob.subscribe(new Action1<String>() {
@Override
public void call(String v) {
System.out.println("onNext: " + v);
}
});
}
使用Java 8 lambdas / closures更紧凑;它看起来像这样:
fWorld.subscribe((v) -> {
System.out.println("onNext: " + v);
})
// - or while also including error handling
fWorld.subscribe((v) -> {
System.out.println("onNext: " + v);
}, (exception) -> {
exception.printStackTrace();
})
有关Observable的更多信息,请访问:http://reactivex.io/documentation/observable.html