SpringBoot 2.0 已经发布多时,一直不知道它有什么用,只是知道它有个webflux。今天就来学习一下,看一下是否有必要升级到新版本?
如果你是使用得STS来创建项目的话将会很简单,直接选择web flux模块就好。SpringBoot选择最新稳定的2.1.4.RELEASE。
完整pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mike</groupId>
<artifactId>flux</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mike-flux</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建启动类:(使用STS会自动创建)
package com.mike;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MikeFluxApplication {
public static void main(String[] args) {
SpringApplication.run(MikeFluxApplication.class, args);
}
}
有过前端工作经验的小伙伴,对路由肯定不陌生,Vue react中都有统一的路有管理。现在SpringBoot也可以这样来写了。后端的小伙伴可以把它理解为你之前写的controller。
先定义一个处理类:
package com.mike.handler;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
/**
* The class HelloHandler
*
*/
@Component
public class HelloHandler {
public Mono<ServerResponse> sayHello(ServerRequest req) {
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(req.queryParam("name").get()));
}
}
Mono 定义返回单个结果,定义了响应数据类型以及数据。我是从请求参数中取得 name 参数进行返回。
有了处理类,我们就需要定义什么样的路由交给它来处理,要将路有何处理程序进行mapping:
package com.mike.router;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import com.mike.handler.HelloHandler;
/**
* The class HelloRouter
*
*/
@Configuration
public class HelloRouter {
@Bean
public RouterFunction<ServerResponse> hello(HelloHandler handle){
return RouterFunctions.route(RequestPredicates.GET("/hello")
.and(RequestPredicates.accept(MediaType.APPLICATION_JSON_UTF8))
,handle::sayHello);
}
}
我们定义了 /hello 的请求交给我们的处理类去处理,这样一次完整的请求就搞定了。启动程序,访问 http://localhost :8080/hello?name=mike 就可以看到页面上的结果了。
Mono 或 Flux 来包裹。 controller 。 修改 HelloHandler :
public Mono<ServerResponse> sayHello(ServerRequest req) {
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8)
.syncBody(BodyInserters.fromObject(req.queryParam("name").get()));
}
访问 http://localhost :8080/hello?name=mike 你会发现你获取不到 name 的值,这就是异步编程带来的问题,相信许多前端的小伙伴很熟悉这样的问题。
关于webflux如果你有更深的理解,希望可以回复一起交流。
如果想要学习更多知识,可以关注下我的公众号: