WebFlux

阻塞模式

非阻塞模式

概念

响应式api

编程模型

web flux提供了两种编程模型:

web mvc or web flux?

批注 2020-04-20 152918

服务器

在 web flux中,可以跨tomcat、jetty等容器使用

性能

非阻塞方式进行操作需要更多的工作,这可能会稍微增加所需的处理时间 使用响应式的好处在于能够以较少的固定数量线程以及更少的内存资源进行更好的扩展

并发模型

响应式核心

HttpHandler

一个可以处理请求并且响应的单一方法 不同的服务器具有不同的api

WebHandler

spring web基于httphandler封装了WebHandler

Filters

可以使用 WebFilter 处理请求

Exceptions

可以使用ExceptionHandler来处理请求与响应中的异常

Codecs

web flux 提供了一些封装来负责数据的序列化与反序列化

DispatcherHandler

类似于mvc中的DispatcherServlet

负责对请求的统一控制与转发

使用

传统方式

跟MVC一样 可以使用controller等相关注解进行使用

函数式端点

概览

class Handler {
    public  Mono<ServerResponse> listPeople(ServerRequest request) {
        // ...
    }
    public Mono<ServerResponse> createPerson(ServerRequest request) {
        // ...
    }
    public Mono<ServerResponse> getPerson(ServerRequest request) {
        // ...
    }
}
Handler handler = new Handler();
// 定义路由映射
RouterFunction<ServerResponse> route = route()
        .GET("/person/{id}", accept(APPLICATION_JSON), handler::getPerson)
        .GET("/person", accept(APPLICATION_JSON), handler::listPeople)
        .POST("/person", handler::createPerson)
        .build();

ServerRequest

提供了一个访问请求数据的东西

Mono<String> string = request.bodyToMono(String.class);

ServerResponse

这玩意是不可变的,所以需要手动来创建

public  Mono<ServerResponse> listPeople(ServerRequest request) {
    return ok().body(Mono.just("people list"), String.class);
}

路由判断

// 只有person/1才会被处理
route()
.GET("/person/{id}", accept(APPLICATION_JSON).and(request-> "1".equals(request.pathVariable("id"))), handler::getPerson)

路由优先级

RouterFunction<ServerResponse> route = route()
    .GET("/person/{id}", accept(APPLICATION_JSON), handler::getPerson) //1
    .GET("/person", accept(APPLICATION_JSON), handler::listPeople)  // 2
    .POST("/person", handler::createPerson)  // 3
    .add(otherRoute)  // 添加其他路由
    .build();

嵌套路由

RouterFunction<ServerResponse> route = route()
    .path("/person", builder -> builder 
        .GET("/{id}", accept(APPLICATION_JSON), handler::getPerson)
        .GET("", accept(APPLICATION_JSON), handler::listPeople)
        .POST("/person", handler::createPerson))
    .build();

运行

@EnableWebFlux

@Bean
RouterFunction<ServerResponse> routerFunction(){
  ...
}

过滤器

route()
  .before(req->{
      System.out.println(req.path()+"before");
      return req;
  })
  .GET("/person/{id}", accept(APPLICATION_JSON).and(request-> "1".equals(request.pathVariable("id"))), handler::getPerson)
  .GET("/person", accept(APPLICATION_JSON), handler::listPeople)
  .POST("/person", handler::createPerson)
  .after((req,res)->{
      System.out.println(req.path()+"after");
      return res;
  })
  .build();

或者另外一种方式:

route()
 .GET("/person/{id}", accept(APPLICATION_JSON).and(request-> "1".equals(request.pathVariable("id"))), handler::getPerson)
 .GET("/person", accept(APPLICATION_JSON), handler::listPeople)
 .POST("/person", handler::createPerson)
 .filter((req,res)->{
     System.out.println(req.path()+"before");
     return res.handle(req);
 })
 .build();