• Spring WebFlux入门实践


    简单介绍

    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

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter</artifactId>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.springframework.boot</groupId>
    8. <artifactId>spring-boot-starter-webflux</artifactId>
    9. </dependency>
    10. <dependency>
    11. <groupId>org.springframework.boot</groupId>
    12. <artifactId>spring-boot-starter-test</artifactId>
    13. <scope>test</scope>
    14. <exclusions>
    15. <exclusion>
    16. <groupId>org.junit.vintage</groupId>
    17. <artifactId>junit-vintage-engine</artifactId>
    18. </exclusion>
    19. </exclusions>
    20. </dependency>
    21. </dependencies>
    22. 复制代码

    2. 编写代码

    1. Controller层将使用几种不同的风格返回结果
    2. service层则是一个耗时5秒的方法

    Controller

    1. @RestController
    2. public class WebFluxController {
    3. private static final Logger log = LoggerFactory.getLogger(WebFluxController.class);
    4. @Resource
    5. private WebFluxService webFluxService;
    6. /**
    7. * 方式一
    8. * @param id
    9. * @return
    10. */
    11. @GetMapping("/hello1")
    12. public Mono<String> helloWebFlux(@RequestParam("id") String id){
    13. log.info("webflux start..");
    14. Mono<String> result = Mono.fromSupplier(()-> webFluxService.helloWebFlux(id));
    15. log.info("webflux end..");
    16. return result;
    17. }
    18. /**
    19. * 方式二
    20. * @param id
    21. * @return
    22. */
    23. @GetMapping("/hello2")
    24. public Mono<String> helloWebFlux2(@RequestParam("id") String id){
    25. return Mono.just("hello")
    26. .publishOn(Schedulers.elastic())
    27. .map(s -> webFluxService.helloWebFlux(id));
    28. }
    29. /**
    30. * MVC方式
    31. * @param id
    32. * @return
    33. */
    34. @GetMapping("/hello3")
    35. public String helloWebFlux3(@RequestParam("id") String id){
    36. log.info("mvc start..");
    37. String result = webFluxService.helloWebFlux(id);
    38. log.info("mvc end..");
    39. return result;
    40. }
    41. /**
    42. * Flux : 返回0-n个元素
    43. * 注:需要指定MediaType
    44. * @return
    45. */
    46. @GetMapping(value = "/hello4", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    47. private Flux<String> flux() {
    48. Flux<String> result = Flux
    49. .fromStream(IntStream.range(1, 5).mapToObj(i -> {
    50. try {
    51. TimeUnit.SECONDS.sleep(1);
    52. } catch (InterruptedException e) {
    53. }
    54. return "flux data--" + i;
    55. }));
    56. return result;
    57. }
    58. }
    59. 复制代码

    Service

    1. public interface WebFluxService {
    2. String helloWebFlux(String id);
    3. }
    4. 复制代码
    1. @Service
    2. public class WebFluxServiceImpl implements WebFluxService {
    3. @Override
    4. public String helloWebFlux(String id) {
    5. try {
    6. TimeUnit.SECONDS.sleep(5);
    7. } catch (InterruptedException e) {
    8. }
    9. return "Hello Webflux" + id;
    10. }
    11. }
    12. 复制代码

    对比MVC和Webflux的区别

    1. 浏览器端感受的结果都一样,都是5秒后响应。
    2. 后端日志

    一个阻塞等待,一个异步等待。

    1. WebFlux支持 服务器推送 ,如接口 /hello4

    3. Webflux的编程式请求方式

    1. @Component
    2. public class HiHandler {
    3. public Mono<ServerResponse> sayHi(ServerRequest request){
    4. return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
    5. .body(BodyInserters.fromValue("Hi,this is SpringWebFlux"));
    6. }
    7. }
    8. 复制代码
    1. @Configuration
    2. public class WebFluxFunction {
    3. @Bean
    4. public RouterFunction<ServerResponse> routSayHi(HiHandler handler){
    5. return RouterFunctions
    6. .route(RequestPredicates.GET("/hi")
    7. .and(RequestPredicates.accept(MediaType.ALL)),handler::sayHi);
    8. }
    9. }
    10. 复制代码

    请求127.0.0.1:8080/hi就会返回 Hi,this is SpringWebFlux ;

    来源:https://juejin.cn/post/7136076166812680199

  • 相关阅读:
    JAVA客户端使用账号密码调用influxdb2报错:{“code“:“unauthorized“,“message“:“Unauthorized“}
    提升写作效率:ChatGPT助力学术论文撰写
    基于目标检测模型实现遥感图像检测
    计算机网络第五章——传输层(下)
    centos7安装virtualenv
    力扣(LeetCode)115. 不同的子序列(C++)
    [云原生] K8s之pod控制器详解
    初识CNN卷积神经网络
    网络爬虫:如何有效的检测分布式爬虫
    尚硅谷Vue系列教程学习笔记(14)
  • 原文地址:https://blog.csdn.net/Chenhui98/article/details/126554245