SpringBoot WebFlux响应式编程

举报
小毕超 发表于 2022/06/23 23:41:05 2022/06/23
【摘要】 SpringBoot WebFlux响应式编程 一、简介 Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架。 与Spring MVC不同,它不需要Se...

SpringBoot WebFlux响应式编程

一、简介

Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架。 与Spring MVC不同,它不需要Servlet API,完全异步和非阻塞, 并通过Reactor项目实现Reactive Streams规范。 并且可以在诸如Netty,Undertow和Servlet 3.1+容器的服务器上运行。
Flux 和 Mono 是 Reactor 中的两个基本概念。Flux 表示的是包含 0 到 N 个元素的异步序列。 在该序列中可以包含三种不同类型的消息通知:正常的包含元素的消息、序列结束的消息和序列出错的消息。 当消息通知产生时,订阅者中对应的方法 onNext(), onComplete()和 onError()会被调用。Mono 表示的是包含 0 或者 1 个元素的异步序列。 该序列中同样可以包含与 Flux 相同的三种类型的消息通知。Flux 和 Mono 之间可以进行转换。 对一个 Flux 序列进行计数操作,得到的结果是一个 Mono对象。把两个 Mono 序列合并在一起,得到的是一个 Flux 对象。

二、Flux和Mono

1)简单业务而言:和其他普通对象差别不大,复杂请求业务,就可以提升性能
2)通俗理解:
Mono 表示的是包含 0 或者 1 个元素的异步序列
mono->单一对象 User redis->用户ID-》唯一的用户Mono

Flux 表示的是包含 0 到 N 个元素的异步序列
flux->数组列表对象 List redis->男性用户->Flux
Flux 和 Mono 之间可以进行转换

三 Spring WebFlux 两种风格

1. 基于注解

@RestController 
@RequestMapping("/ users")
public  class MyRestController {

	@GetMapping("/ {user}")
	 public Mono <User> getUser( @PathVariable Long user){
		 // ...
	}
	
	@GetMapping("/ {user} / customers")
	 public Flux <Customer> getUserCustomers( @PathVariable Long user){
		 // ...
	}
	
	@DeleteMapping("/ {user}")
	 public Mono <User> deleteUser( @PathVariable Long user){
		 // ...
	}

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

2. 基于功能

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;

import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;

@Configuration
public class RoutingConfiguration {
    @Bean
    public RouterFunction<ServerResponse> monoRouterFunction(UserHandler userHandler) {
        return route(GET("/{user}").and(accept(APPLICATION_JSON)),userHandler::getUser)
                .andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
                .andRoute(DELETE("/ {user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

@Component
public class UserHandler {

	public Mono<ServerResponse> getUser(ServerRequest request){
		 // ...
	}
	
	public Mono <ServerResponse> getUserCustomers(ServerRequest request){
		 // ...
	}
	
	public Mono <ServerResponse> deleteUser(ServerRequest  request){
		 // ...
	}
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

注意点

Spring WebFlux应用程序不严格依赖于Servlet API,因此它们不能作为war文件部署,也不能使用src/main/webapp目录

可以整合多个模板引擎
除了REST Web服务外,您还可以使用Spring WebFlux提供动态HTML内容。Spring WebFlux支持各种模板技术,包括Thymeleaf,FreeMarker

三、 SpringBoot简单使用

1. pom

如果有spring-boot-starter-web去掉换成下面依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

  
 
  • 1
  • 2
  • 3
  • 4

2. 使用

@RestController
public class TestFluxController {

    @GetMapping("/GetTest1")
    public Mono<String> getTest(){
        return Mono.fromCallable(()->{
            Thread.sleep(5000);
            return "success";
        });
    }

    @GetMapping("/GetTest2/{param}")
    public Mono<String> getTest2(@PathVariable("param")String param){
        return Mono.fromCallable(()->{
            Thread.sleep(500);
            return "success param = " + param;
        });
    }

    @PostMapping("/GetTest3")
    public Mono<String> getTest3(String param){
        return Mono.fromCallable(()->{
            Thread.sleep(500);
            return "success param = " + param;
        });
    }

    @PostMapping("/GetTest4")
    public Mono<String> getTest4(@RequestBody Map<String,Object> map){
        return Mono.fromCallable(()->{
            Thread.sleep(500);
            return "success param = " + map.toString();
        });
    }

//    @GetMapping(value = "/GetTest5",produces = "text/event-stream")
    @GetMapping(value = "/GetTest5",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> getTest5(){
        return Flux.fromStream(IntStream.range(1,5).mapToObj(i->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "localhost - > "+i;
        }));
    }

}



  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

文章来源: blog.csdn.net,作者:小毕超,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_43692950/article/details/107449684

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。