java异步处理rest服务_Spring MVC异步处理简介

Spring MVC异步处理简介

相关系列文章:

本文讲到的所有特性皆是基于Servlet 3.0 Async Processing的,不是基于Servlet 3.1 Async IO的。

Callable>

A Callable> can be returned when the application wants to produce the return value asynchronously in a thread managed by Spring MVC.

用于异步返回结果,使用的是Spring MVC的AsyncTaskExecutor,Spring MVC使用CallableMethodReturnValueHandler负责处理它。

@RestController

public class CallableController {

@RequestMapping("callable-hello")

public Callable hello() {

return () -> new SlowJob("CallableController").doWork();

}

}

用浏览器访问:http://localhost:8080/callable-hello 查看返回结果。

DeferredResult>

A DeferredResult> can be returned when the application wants to produce the return value from a thread of its own choosing.

用于异步返回结果,使用的是client code自己的thread,Spring MVC使用DeferredResultMethodReturnValueHandler负责处理它。

@RestController

public class DeferredResultController {

@Autowired

@Qualifier("customExecutorService")

private ExecutorService executorService;

@RequestMapping("deferred-result-hello")

public DeferredResult hello() {

DeferredResult deferredResult = new DeferredResult<>();

executorService.submit(() -> {

try {

deferredResult.setResult(new SlowJob("DeferredResultController").doWork());

} catch (Exception e) {

deferredResult.setErrorResult(e);

}

});

return deferredResult;

}

}

在这个例子里使用了ExecutorService(见ExecutorServiceConfiguration),你也可以根据实际情况采用别的机制来给DeferredResult.setResult。

用浏览器访问:http://localhost:8080/deferred-result-hello 查看返回结果。

ListenableFuture> or CompletableFuture>/CompletionStage>

A ListenableFuture> or CompletableFuture>/CompletionStage> can be returned when the application wants to produce the value from a thread pool submission.

用于异步返回结果,使用client code自己的thread pool,Spring MVC使用DeferredResultMethodReturnValueHandler负责处理它。

@RestController

public class ListenableFutureController {

@Autowired

@Qualifier("customExecutorService")

private ExecutorService executorService;

@RequestMapping("listenable-future-hello")

public ListenableFutureTask hello() {

ListenableFutureTask listenableFutureTask = new ListenableFutureTask<>(

() -> new SlowJob("ListenableFutureController").doWork());

executorService.submit(listenableFutureTask);

return listenableFutureTask;

}

}

用浏览器访问:http://localhost:8080/listenable-future-hello 查看返回结果。

@RestController

public class CompletionFutureController {

@RequestMapping("completable-future-hello")

public CompletableFuture hello() {

return CompletableFuture

.supplyAsync(() -> new SlowJob("CompletionFutureController").doWork());

}

}

用浏览器访问:http://localhost:8080/completable-future-hello 查看返回结果。

ResponseBodyEmitter

A ResponseBodyEmitter can be returned to write multiple objects to the response asynchronously; also supported as the body within a ResponseEntity.

用于异步的写入多个消息,使用的是client code自己的thread,Spring MVC使用ResponseBodyEmitterReturnValueHandler负责处理它。

@RestController

public class ResponseBodyEmitterController {

@Autowired

@Qualifier("customExecutorService")

private ExecutorService executorService;

@RequestMapping("response-body-emitter-hello")

public ResponseBodyEmitter hello() {

ResponseBodyEmitter emitter = new ResponseBodyEmitter();

executorService.submit(() -> {

try {

for (int i = 0; i < 5; i++) {

String hello = new SlowJob("ResponseBodyEmitterController").doWork();

emitter.send("Count: " + (i + 1));

emitter.send("\n");

emitter.send(hello);

emitter.send("\n\n");

}

emitter.complete();

} catch (Exception e) {

emitter.completeWithError(e);

}

});

return emitter;

}

}

用浏览器访问:http://localhost:8080/response-body-emitter-hello 查看返回结果。

SseEmitter

An SseEmitter can be returned to write Server-Sent Events to the response asynchronously; also supported as the body within a ResponseEntity.

作用和ResponseBodyEmitter类似,也是异步的写入多个消息,使用的是client code自己的thread,区别在于它使用的是Server-Sent Events。Spring MVC使用ResponseBodyEmitterReturnValueHandler负责处理它。

@RestController

public class SseEmitterController {

@Autowired

@Qualifier("customExecutorService")

private ExecutorService executorService;

@RequestMapping("sse-emitter-hello")

public ResponseBodyEmitter hello() {

SseEmitter emitter = new SseEmitter();

executorService.submit(() -> {

try {

for (int i = 0; i < 5; i++) {

String hello = new SlowJob("SseEmitterController").doWork();

StringBuilder sb = new StringBuilder();

sb.append("Count: " + (i + 1)).append(". ").append(hello.replace("\n", ""));

emitter.send(sb.toString());

}

emitter.complete();

} catch (Exception e) {

emitter.completeWithError(e);

}

});

return emitter;

}

}

用浏览器访问:http://localhost:8080/sse-emitter-hello 查看返回结果。

StreamingResponseBody

A StreamingResponseBody can be returned to write to the response OutputStream asynchronously; also supported as the body within a ResponseEntity.

用于异步write outputStream,使用的是Spring MVC的AsyncTaskExecutor,Spring MVC使用StreamingResponseBodyReturnValueHandler负责处理它。要注意,Spring MVC并没有使用Servlet 3.1 Async IO([Read|Write]Listener)。

@RestController

public class StreamingResponseBodyController {

@RequestMapping("streaming-response-body-hello")

public StreamingResponseBody hello() {

return outputStream -> {

String hello = new SlowJob("CallableController").doWork();

outputStream.write(hello.getBytes());

outputStream.flush();

};

}

}

用浏览器访问:http://localhost:8080/streaming-response-body-hello 查看返回结果。

配置MVC Async

AsyncTaskExecutor

Spring MVC执行异步操作需要用到AsyncTaskExecutor,这个可以在用WebMvcConfigurer.configureAsyncSupport方法来提供(相关文档)。

如果不提供,则使用SimpleAsyncTaskExecutor,SimpleAsyncTaskExecutor不使用thread pool,因此推荐提供自定义的AsyncTaskExecutor。

需要注意的是@EnableAsync也需要用到AsyncTaskExecutor,不过Spring MVC和它用的不是同一个。

顺带一提,EnableAsync默认也使用SimpleAsyncTaskExecutor,可以使用AsyncConfigurer.getAsyncExecutor方法来提供一个自定义的AsyncTaskExecutor。

Interceptors

AsyncHandlerInterceptor,使用WebMvcConfigurer.addInterceptors注册

CallableProcessingInterceptor[Adapter],使用WebMvcConfigurer.configureAsyncSupport注册

DeferredResultProcessingInterceptor[Adapter],使用WebMvcConfigurer.configureAsyncSupport注册

WebAsyncManager

WebAsyncManager是Spring MVC管理async processing的中心类,如果你可以阅读它的源码来更多了解Spring MVC对于async processing的底层机制。

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值