响应式编程实操:SpringWebFlux函数式编程|青训营

82 阅读2分钟

函数式开发模式

  • RequestPredicate —— 声明将会被处理的请求类型
  • RouterFunction —— 声明一个匹配的请求应该如何被路由到处理代码中
  • ServerRequest —— 表示 HTTP 请求,包括对头和正文信息的访问
  • ServerResponse —— 表示 HTTP 响应,包括头和正文信息

HandlerFunction相当于Controller中的具体处理方法,输入为请求,输出为装在Mono中的响应:

Mono<T extends ServerResponse> handle(ServerRequest request);

RouterFunction,路由,相当于@RequestMapping,用来判断什么样的url映射到那个具体的HandlerFunction,输入为请求,输出为装在Mono里边的Handlerfunction:

Mono<HandlerFunction<T>> route(ServerRequest request);

//带s的类一般就是工具类

//导入静态方法,就可以直接用

import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route; 
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
import static reactor.core.publisher.Mono.just;
​
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
@Configuration //配置类
public class RouterFunctionConfig {
    @Bean
    public RouterFunction<?> helloRouterFunction() {
        return route(GET("/hello"),
                     request -> ok().body(just("Hello World!"), String.class))
                .andRoute(GET("/bye"),
                     request -> ok().body(just("See ya!"), String.class));
    }
}

1、RouterFunctions 中的 route() 方法接受两个参数:RequestPredicate 和处理请求匹配的函数HandlerFunction<T>。返回值是RouterFunction<T>

2、RequestPredicates中的GET()方法:参数为路径,返回值为 RequestPredicate,声明了一个get请求及路径

3、request -> ok().body(just("Hello World!"), String.class)

lambda表达式定义一个HandlerFunction:输入参数为ServerRequestok()方法是为了返回一个200状态码,body()方法有两个输入参数,一是Publisher(Mono或者Flux),二是元素类型,所以返回值是Mono<ServerResponse>

4、andRoute():声明另一个请求和对应的处理方法

5、处理请求的函数也可以直接写成方法引用的形式,比如:

@Configuration
public class RouterFunctionConfig {
    @Autowired
    private TacoRepository tacoRepo; //持久层
    
    @Bean
    public RouterFunction<?> routerFunction() {
        return route(GET("/design/taco"), this::recents)
            .andRoute(POST("/design"), this::postTaco);
    }
​
    public Mono<ServerResponse> recents(ServerRequest request) {
        return ServerResponse.ok()
            .body(tacoRepo.findAll().take(12), Taco.class);//提取前12个元素
    }
​
    public Mono<ServerResponse> postTaco(ServerRequest request) {
        Mono<Taco> taco = request.bodyToMono(Taco.class); //将指定类型转为Mono流
        Mono<Taco> savedTaco = tacoRepo.save(taco);
        return ServerResponse
            .created(URI.create("http://localhost:8080/design/taco/" +savedTaco.getId())) 
            //创建uri,返回BodyBuilder
            .body(savedTaco, Taco.class); //返回Mono<ServerResponse>
    }
}