私はspring mvcでRESTfulなapiアプリケーションを構築しています。spring mvcは反応性のストリームと統合します
最近、私はspring mvcと反応ストリーム(rxjavaとproject-reactorのようなもの)の間に何か統合を行い、アプリケーションをより反応性のあるものにしようとしていました。
私はちょうど以下のようにいくつかのデモを構築しています両方のデモを実行している間、私はPublishSubject
private SerializedSubject<StreamResult, StreamResult> subject = PublishSubject.<StreamResult>create().toSerialized();
public ReactiveStreamController() {
this.subject.subscribe(streamResult -> {
String id = streamResult.getRequest().getParameter("id");
System.out.println("[" + Thread.currentThread().getName() + "] request received. id = " + id);
String random = StringUtils.isBlank(id) ? StringUtils.EMPTY : id;
ResponseVO vo = new ResponseVO(200, "success = " + random);
streamResult.getFuture().complete(vo);
}, Throwable::printStackTrace);
}
@ResponseBody
@RequestMapping(value = "/rxJava", method = RequestMethod.GET)
public CompletableFuture<ResponseVO> rxJavaController(HttpServletRequest httpServletRequest) {
StreamResult sr = new StreamResult();
sr.setRequest(httpServletRequest);
subject.onNext(sr);
return sr.getFuture();
}
2.forプロジェクトの原子炉
@ResponseBody
@RequestMapping(value = "/reactorCodeNew", method = RequestMethod.GET)
public CompletableFuture<ResponseVO> reactorCoreNewParadigm(HttpServletRequest servletRequest) {
Mono<ResponseVO> mono = Mono.just(servletRequest)
.subscribeOn(executorService)
.map(request -> {
String id = request.getParameter("id");
System.out.println("[" + Thread.currentThread().getName() + "] request received. id = " + id);
String random = StringUtils.isBlank(id) ? StringUtils.EMPTY : id;
ResponseVO vo = new ResponseVO(200, "success = " + random);
return vo;
})
.timeout(Duration.ofSeconds(2), Mono.just(new ResponseVO(500, "error")));
return mono.toCompletableFuture();
}
を使用し、
1.for rxjava 、私はちょうどjavaのCompletableFutureを使用してコントローラメソッドの中に供給することとの間にあまりにも多くの違いがあるとは思わない。
私はリアクティブストリームを理解して、私が望むのは、サーブレットリクエストをストリームとして扱い、バックプレッシャーのような機能でコスメします。
私は知りたいことがあります: 1.アプリケーションをより反応的にする良い方法はありますか? 2. spring mvcと反応ストリームを統合するのは正しいか互換性がありますか?はいの場合、どのように背圧のような機能を実行できますか?
私はたぶん私がコントローラでcompletablefutureを返す理由を宣言するのを忘れていたかもしれませんが、実際には、私はカスタマイズされたMethodReturnValueHandlerを注入して、CompletableFutureをDefferdResultに変換します。
public class CompletableFutureMethodReturnValueHandler extends DeferredResultMethodReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return CompletableFuture.class.isAssignableFrom(returnType.getParameterType());
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
CompletableFuture<?> completableFuture = (CompletableFuture<?>) returnValue;
super.handleReturnValue(CompletableDeferredResult.newInstance(completableFuture), returnType, mavContainer, webRequest);
}
}
最近、正確にこの春のブログが投稿されました:https://spring.io/blog/2016/07/20/notes-on-reactive-programming-part-iii-a-simple-http-server-application – Will