功能与api
背景
Netty作为java领域首屈一指的nio框架,其以优越的性能被众多中间件所使用。但到了java的web开发领域,却很难享受到Netty的性能优势。其原因在于传统web开发基于servlet容器,许多依赖和开发框架都是基于servlet实现的,比如spring。而netty为了保持代码的简单和高效,并没有实现servlet标准,这就导致将web容器迁移到netty后许多框架和第三方库不能使用,迁移的成本过大。但spring webflux出现改变了这一现状。她在兼容原有mvc开发方式的同时,重写和实现了大量第三方库,在提升性能的同时,降低了迁移的成本。同时spring webflux适配多种web容器,即使仍然使用tomcat也是可以的。
接口声明
接口声明除了保留原有注解式声明的方式,为了满足reactor的编程风格,额外支持了函数式声明的方式。通工具类RouterFunctions过构造RounterFunction对象,并向Spring注入实现函数式接口声明。
@Bean
public TestHandler testHandler() {
return new TestHandler();
}
@Bean
public RouterFunction routes(TestHandler testHandler) {
return RouterFunctions.route(RequestPredicates.POST("/route"),
testHandler::echoName);
}
@GetMapping("anno")
public String sayHello(String name) {
return "hello world! " + name;
}
class TestHandler {
public Mono echoName(ServerRequest request) {
return request.bodyToMono(Post.class)
.map(Post::getName)
.flatMap(name -> ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(BodyInserters.fromObject("hello world!" + name)));
}
}
在WebFlux中,request和respose不再是原来的ServletRequest和ServletRequest,取而代之的是ServerRequest和ServerResponse。这两个对象是webflux新出现的。首先webflux底层如果使用了reactor-netty,那么自然就没有所谓的servlet一说,另外ServerRequest和ServerResponse提供了对non-blocking和backpressure特性的支持,提供了将Http消息内容转换成Mono和Flux的方法,使响应式编程成为了可能。
过滤器Filter
过滤器的使用方法和spring mvc类似,不过与ServerRequest和ServerResponse相同的是,webflux提供了一个新的过滤器接口WebFilter以提供对Mono和Flux的支持。代码如下:
@Component
public class DemoWebFilter implements WebFilter{
@Override
public Mono filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
if (!serverWebExchange.getRequest().getHeaders().containsKey("token")) {
serverWebExchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return Mono.empty();
}
return webFilterChain.filter(serverWebExchange);
}
}
值得注意的是Mono这个返回值,在框架的很多地方都会用到。他意味着一个空的Mono,对于任何读取,他会立刻发出一个complete信号。相比与直接返回void,Mono作为方法的返回值时,可以对该方法进行链式调用。另外虽然Mono虽然没有返回值,但是其本身的complete或者error状态,也可以注册回调进行异步处理。
异常处理
在Spring Webflux中,异常分两种。一是controller中方法抛出的异常,这在webflux中同样可以像在mvc中用@ExceptionHandler声明异常处理方法。二是在WebHandler API这种比较偏底层的api,典型的是WebFilter,异常处理使用了支持Mono的新接口:WebExceptionHandler,可用于处理来自WebFilter链和WebHandler的异常。使用WebExceptionHandler时,只要将其声明为Spring bean即可自动注入并使用,并可选择通过bean声明上的&#