首页 > 其他分享 >Spring 赌上未来一击,推出响应式框架 WebFlux,代码更优雅,性能更强!

Spring 赌上未来一击,推出响应式框架 WebFlux,代码更优雅,性能更强!

时间:2023-06-28 16:57:32浏览次数:147  
标签:赌上 响应 Spring 编程 webflux WebFlux person spring

Spring-webflux简介

spring-webflux是spring在5.0版本后提供的一套响应式编程风格的web开发框架,大量测评证明,使用WebFlux开发接口能够大幅提升接口的吞吐量。

这个框架包含了spring-framework和spring mvc,它可以运行在Netty、Undertow以及3.1版本以上的Serlvet容器上。你可以在项目中同时使用spring-webmvc和spring-webflux,或者只用其中一个来开发web应用。

什么是“响应式”

所谓响应式,举个例子,当调用一个api获取数据时,无需阻塞等待数据返回,而是当有数据返回时会进行告知。可见响应式是非阻塞的,意味着调用方法后,CPU可以去做别的事情,当接收到数据响应时CPU再回来处理,这种方式提高了系统的吞吐量。

而响应式编程,其实是为这种异步非阻塞的流式编程制定的一套标准。流式编程已不陌生了,Java8提供的stream api就是这种风格。这套标准包括对运行环境(JVM、JavaScript)以及网络协议相关的规范。

Spring-webflux的响应式API

Spring-webflux框架是基于Reactor这个开源项目开发的。Reactor框架是跟Spring紧密配合的。

它提供了两种API类型,分别是Mono和Flux;

// Mono一般作用于单个对象
Mono<Person> person = personDao.getPerson(personId);
// Flux一般作用于多个对象
Flux<Person> people = personDao.listAllPeople();

尽管webflux框架基于Reactor,它也能与其他的响应式框架同时使用,比如RxJava。

推荐一个开源免费的 Spring Boot 实战项目:

https://github.com/javastacks/spring-boot-best-practice

选择Spring-webmvc还是Spring-webflux呢

这两个web框架分别代表着两种不同类型的编程流派,官方给出了一个图作为对比如下

根据官方的建议有以下几点可以作为参考:

  • 如果你已经使用了Spring-webmvc进行开发,并且项目运行良好,就无需更改了;何况现在大多数的三方库都是阻塞的,并不能发挥出非阻塞的优势。
  • webflux提供了相当多的选择;在服务层,可以使用(Netty, Tomcat, Jetty, Undertow, 和3.1版本以上的Servlet容器)作为web服务;在应用层,可以选择用@Controller定义还是使用函数编程定义;在编程风格上,可以选择用Reactor、RxJava或其他。
  • 如果你钟爱Java8提供的lambda表达式这种轻量级、函数式的编程风格,那么建议选择用webflux;同时对于一些轻量级应用,或者复杂度比较低的微服务,建议使用webflux以便更好的进行控制。
  • 在微服务架构中,可以将webmvc和webflux项目混合使用。两个框架都可以使用@Controller这种注解的方式,使得项目的重用更加容易。
  • 评估一个项目是否应该选择webflux的最简单的方式是,依据项目中是否会使用很多的阻塞API,比如JDBC或者一些阻塞式的API就不适用与webflux项目。
  • 如果一个webmvc项目中有很多的外部系统调用,可以试试响应式的WebClient,它能直接从Controller的方法中返回响应式结果。
  • 响应式编程的学习路线是比较陡峭的,所以如果你身在一个大型的团队中,要考虑投入的成本;不过可以用用WebClient来体验下响应式编程。

Spring-webflux不仅可以支持在Tomcat、Jetty以及3.1版本以上的Servlet容器上,还能够运行在非Servlet的服务器之上,比如Netty、Undertow等。

使用Springboot构建一个webflux应用,默认就是使用Netty,因为Netty本身就是非阻塞式的实现。

并发模型

尽管webmvc和webflux都支持使用注解来定义一个Controller,但是其实现方式完全不同。

webmvc是一个Servlet应用,实现是阻塞式IO,其维护一个线程池来处理每一个用户请求,也就是当Servlet容器启动时,就会创建比如10个线程出来,因此系统吞吐量的瓶颈在于有限的连接数和阻塞的请求处理过程。

webflux可以基于netty这样的NIO网络框架,它只需要很少的几个工作线程(Event loop worker)就能够处理并响应请求。由于无需阻塞等待方法返回,CPU资源就得到了更好的利用。

webflux并不能让程序运行地更快;而是提高了并发处理请求的能力,即提高了系统吞吐量。

webflux代码示例

Talk is cheap, show me the code

下面让我们来看一下webflux的示例,总的来说使用上是非常便捷的。

我们用Springboot构建一个webflux应用非常简单,仅仅需要加入这么一个依赖

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

首先定义一个对象

public class Person {
    private Integer id;
    private Integer age;
    private String name;
}

然后定义“PersonController”,响应式风格中不再使用@RequestMapping声明地址映射了,而是通过RouterFunctions.route().GET()方法

@Configuration
public class PersonRouter {
    @Resource
    private PersonHandler personHandler;
    @Bean
    public RouterFunction<ServerResponse> personRoutes() {
        return RouterFunctions.route()
                .GET("/person/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), personHandler::getPerson)
                .GET("/person", RequestPredicates.accept(MediaType.APPLICATION_JSON), personHandler::listPeople)
                .POST("/person", personHandler::createPerson)
                .build();
    }
}

在PersonHandler中处理对应的HTTP请求,等同于MVC架构中的Service层

@Component
public class PersonHandler {

    @Resource
    private PersonRepository personDao;

    public Mono<ServerResponse> listPeople(ServerRequest request) {
        Flux<Person> people = personDao.listAllPeople();
        return ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(people, Person.class);
    }

    public Mono<ServerResponse> createPerson(ServerRequest request) {
        Mono<Person> person = request.bodyToMono(Person.class);
        return ServerResponse.ok()
                .build(personDao.savePerson(person));
    }

    public Mono<ServerResponse> getPerson(ServerRequest request) {
        int personId = Integer.parseInt(request.pathVariable("id"));
        return personDao.getPerson(personId)
                .flatMap(person -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue(person))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

}

通过启动日志可以证实Spring-webflux是默认使用Netty提供HTTP服务

项目启动之后浏览器访问http://localhost:8080/person/1就能发现,你的Spring-webflux项目已经正常工作了。

原文链接:https://blog.csdn.net/yasin_huang/article/details/106556935

近期热文推荐:

1.1,000+ 道 Java面试题及答案整理(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!

标签:赌上,响应,Spring,编程,webflux,WebFlux,person,spring
From: https://www.cnblogs.com/javastack/p/17511820.html

相关文章

  • 基于SpringBoot整合Redisson的延迟队列
    一、需求:     1.订单下单超过30分钟以后,如果还未支付,则自动转为取消支付状态 2.订单收货超过七天以后,如果还未评价,则自动转为好评 3.等类似需求二、实现步骤:    1. 引入redisson依赖<dependency><groupId>org.rediss......
  • Springboot实现邮件发送
    本文以QQ邮箱为例,实现springboot邮件发送邮箱设置 主要获取授权码   按照步骤开启服务 获取授权码导入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>配置......
  • Spring Boot:快速入门教程
      来源  https://www.cnblogs.com/xifengxiaoma/p/11019240.html  SpringBoot:快速入门教程......
  • spring mvc 支持options方法
    在web.xml中,添加<init-param> <param-name>dispatchOptionsRequest</param-name> <param-value>true</param-value> </init-param>添加后<servlet> <servlet-name>springdispatcher</servlet-name> <servle......
  • springboot 自定义异常 全局异常处理器
    创建自定义异常类,继承 RuntimeException类1publicclassCustomExceptionextendsRuntimeException{2publicCustomException(Stringmessage){3super(message);4}5}在指定情况下抛出该异常,代码如下: @ServicepublicclassCategoryServiceIm......
  • P4Spring-02-Spring系统架构与Spring-03-核心概念
    Spring-02-Spring系统架构StringFramework是Spring生态圈中最基础的项目,也是其他项目的根基 CoreContainer:核心容器 AOP:面向切面编程Aspects:AOP思想实现 DataAccess:数据访问DataIntegration:数据集成(集成:与其他技......
  • Spring Boot 之 Mybatis Plus 分页插件
    创建分页插件所在的类MybatisPlusConfiguration,并添加注解@Configuration在配置类中添加以下代码@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){/***MybatisPlusInterceptor是插件主体,管理所有的插件*/MybatisPlusInterceptorinter......
  • spring基础之常用组件
    spring基础之常用组件一、基于xml注入bean先看看我们在没有使用注解之前,最早使用xml进行bean的注入是怎么操作的呢?首先我们需要在项目中创建一个.xml文件然后使用bean标签注册一些组件。现在我们就以注册person这个bean进行举例。先创建一个需要注册的bean实例@Data@AllArgs......
  • SpringBoot接入Chat-GPT3
    创建一个APIKeyAPIKey创建网址:https://platform.openai.com/account/api-keys先登录OpenAI账号登陆后创建一个APIKey起一个名字点击创建,生成一个APIKey,记录下这个APIKey后续会用。可以在官网看到剩余容量,账号默认会送$18刀的容量,超过需要购买。在SpringB......
  • SpringCloud学习-2
    SpringCloud学习第二天Eureka相关配置eureka:client:service-url:defaultZone:http://127.0.0.1:10087/eureka#设置eureka服务注册的地址register-with-eureka:false#不注册自己,自己不会显示在服务列表中registry-fetch-interval-seconds:30#......