spring-webflux是spring在5.0版本后提供的一套 响应式 编程风格的web开发框架。
这个框架包含了spring-framework和spring mvc,它可以运行在Netty、Undertow以及3.1版本以上的Serlvet容器上。
你可以在项目中同时使用spring-webmvc和spring-webflux,或者只用其中一个来开发web应用。
所谓响应式,举个例子,当调用一个api获取数据时,无需阻塞等待数据返回,而是当有数据返回时会进行告知。可见响应式是 非阻塞 的,意味着调用方法后,CPU可以去做别的事情,当接收到数据响应时CPU再回来处理,这种方式提高了系统的吞吐量。
而响应式编程,其实是为这种 异步非阻塞的流式编程 制定的一套标准。流式编程已不陌生了,Java8提供的stream api就是这种风格。这套标准包括对运行环境(JVM、JavaScript)以及网络协议相关的规范。
0. 演示项目的目录结构

1. 创建一个springboot工程并引入依赖
我用到的springboot版本为2.3.7
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
-
- <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>
- <exclusions>
- <exclusion>
- <groupId>org.junit.vintage</groupId>
- <artifactId>junit-vintage-engine</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- 复制代码
2. 编写代码
Controller
- @RestController
- public class WebFluxController {
-
- private static final Logger log = LoggerFactory.getLogger(WebFluxController.class);
- @Resource
- private WebFluxService webFluxService;
-
- /**
- * 方式一
- * @param id
- * @return
- */
- @GetMapping("/hello1")
- public Mono<String> helloWebFlux(@RequestParam("id") String id){
- log.info("webflux start..");
- Mono<String> result = Mono.fromSupplier(()-> webFluxService.helloWebFlux(id));
- log.info("webflux end..");
- return result;
- }
-
- /**
- * 方式二
- * @param id
- * @return
- */
- @GetMapping("/hello2")
- public Mono<String> helloWebFlux2(@RequestParam("id") String id){
- return Mono.just("hello")
- .publishOn(Schedulers.elastic())
- .map(s -> webFluxService.helloWebFlux(id));
- }
-
- /**
- * MVC方式
- * @param id
- * @return
- */
- @GetMapping("/hello3")
- public String helloWebFlux3(@RequestParam("id") String id){
- log.info("mvc start..");
- String result = webFluxService.helloWebFlux(id);
- log.info("mvc end..");
- return result;
- }
-
- /**
- * Flux : 返回0-n个元素
- * 注:需要指定MediaType
- * @return
- */
- @GetMapping(value = "/hello4", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
- private Flux<String> flux() {
- Flux<String> result = Flux
- .fromStream(IntStream.range(1, 5).mapToObj(i -> {
- try {
- TimeUnit.SECONDS.sleep(1);
- } catch (InterruptedException e) {
- }
- return "flux data--" + i;
- }));
- return result;
- }
- }
- 复制代码
Service
- public interface WebFluxService {
- String helloWebFlux(String id);
- }
- 复制代码
- @Service
- public class WebFluxServiceImpl implements WebFluxService {
- @Override
- public String helloWebFlux(String id) {
- try {
- TimeUnit.SECONDS.sleep(5);
- } catch (InterruptedException e) {
- }
- return "Hello Webflux" + id;
- }
- }
- 复制代码
对比MVC和Webflux的区别

一个阻塞等待,一个异步等待。
/hello4- @Component
- public class HiHandler {
- public Mono<ServerResponse> sayHi(ServerRequest request){
- return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
- .body(BodyInserters.fromValue("Hi,this is SpringWebFlux"));
- }
- }
- 复制代码
- @Configuration
- public class WebFluxFunction {
- @Bean
- public RouterFunction<ServerResponse> routSayHi(HiHandler handler){
- return RouterFunctions
- .route(RequestPredicates.GET("/hi")
- .and(RequestPredicates.accept(MediaType.ALL)),handler::sayHi);
- }
- }
- 复制代码
请求127.0.0.1:8080/hi就会返回 Hi,this is SpringWebFlux ;