zoukankan      html  css  js  c++  java
  • Spring 5 WebFlux的反应式编程

    介绍

    Spring WebFlux是Spring对日益增长的阻塞I / O体系结构问题的回应。

    随着数据在我们这个时代变得越来越重要,我们采取的检索和处理数据的方法也在发生变化。 按照惯例,大多数方法都是“阻塞”的,或者说是同步的 。 这意味着访问资源会阻止应用程序访问/处理另一资源,直到处理了先前的资源为止。

    尽管通过高性能应用程序对数据的需求不断增长,但是在有限的数据和资源量的情况下,这是完全可以的,这成为一个巨大的问题。

    解决方案很明显-让更多的文员处理客户。 在软件应用程序方面,这意味着多线程环境和异步,非阻塞调用。

    spring反应式编程

    由Spring MVC组成的Spring流行的servlet堆栈使用访问和处理数据的常规方法作为同步调用。 随着Spring 5的推出,Spring的反应式是在Reactor Core之上构建的。

    Spring的反应式堆栈为Netty和Servlet 3.1+容器提供了额外的支持,从而提高了反应式应用程序的性能:


    spring WebFlux

    Spring WebFlux是Spring MVC的对应模块。 在Spring MVC实现同步,阻塞I / O的地方,Spring WebFlux通过Reactive Streams实现反应编程。

    尽管可以自由地将它们组合在一起,但是通常将使用其中一个。

    Spring WebFlux依赖关系

    通过Spring Initializr初始化一个普通的Spring Boot项目,添加一个依赖项就足够了:

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

    spring-boot-starter-webflux包括spring-web , spring-webflux , spring-boot-starter , spring-boot-starter-reactor-netty等,因此不需要任何其他依赖项。

    对于使用Gradle进行依赖关系管理的应用程序,可以将Spring WebFlux添加到应用程序的build.gradle文件中:

     compile group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '2.2.2.RELEASE' 

     

    在Spring WebFlux中,从任何操作返回的数据都打包到响应流中。 这种方法体现了两种类型,它们是WebFlux应用程序的构建块-Mono和Flux 。

    Mono是返回零个项目或单个项目( 0..1 )的流,而Flux是返回零个或多个项目( 0..N )的流。

    因此,在期望单个(或没有)结果(例如从数据库中检索唯一用户)时,将使用Mono ,而在期望多个结果或某种类型的集合时,将使用Flux 。

    Spring WebFlux控制器

    与我们在经典Spring MVC中使用控制器的方式类似,为了创建异步REST API,我们使用WebFlux控制器。 甚至命名约定也类似,以确保在这两种方法之间轻松转换。

    为了将一个类标记为控制器,我们在类级别使用@RestController批注。

    在类路径中具有Spring WebFlux和Reactor Core依赖项将使Spring知道@RestController实际上是一个反应组件,并添加对MonoFlux支持。

    Spring WebFlux配置

    按照Spring Boot的标准,我们将通过注释处理配置。 @Configuration@EnableWebFlux批注将一个类标记为配置类,Spring的bean管理人员将其注册:

     @Configuration @EnableWebFlux 
    public class WebFluxConfig {
    } 

    要使用或扩展现有的WebFlux配置API,可以扩展WebFluxConfigurer接口:

     @Configuration @EnableWebFlux 
    public class WebFluxConfig implements WebFluxConfigurer {
    } 

    带有Spring WebFlux的CORS

    WebFlux还提供CORS(跨源资源共享)支持,与Spring MVC Servlet堆栈非常相似。 可以在项目级别以及控制器和控制器方法级别设置CORS配置。

    要在项目级别添加CORS配置,您需要从WebFluxConfigurer界面addCorsMappings()方法:

     @Configuration 
    @EnableWebFlux 
    public class WebFluxConfig implements WebFluxConfigurer { 
    @Override 
    public void addCorsMappings(CorsRegistry registry) { 
       registry.addMapping("/api/**") 
              .allowedOrigins("http://www.stackabuse.com") 
              .allowedMethods("GET", "PUT", "DELETE") 
              .allowedHeaders("testHeader") 
              .allowCredentials(true); 
       } 
    } 

    为了更详细地添加CORS配置,使用了@CrossOrigin批注。 这允许在控制器和方法级别指定CORS详细信息。

    在控制器类级别使用@CrossOrigin时,所有方法级别的CORS设置都将从类级别配置继承:

     @CrossOrigin(origins = "https://www.stackabuse.com") 
    @RestController @RequestMapping("/resource") 
    public class ResourceController { 
    @GetMapping("/{id}") 
    public Mono<Resource> getResource(@PathVariable String id) { 
       } 
    } 

    Spring Webflux的安全性

    Spring还为其WebFlux框架提供了标准的安全性选项。 您需要在类级别添加@EnableWebFluxSecurity ,以在项目中启用安全性配置:

     @EnableWebFluxSecurity 
    public class WebfluxSecurity { 
    @Bean 
    public SecurityWebFilterChain springSecurityFilterChain( ServerHttpSecurity http) {     
        http.csrf().disable() .authorizeExchange() .pathMatchers(HttpMethod.GET, 
        "/resource/").hasRole("ADMIN") .pathMatchers("/**").permitAll() .and() 
        .httpBasic(); 
        return http.build(); 
    } 
    } 

    Spring WebFlux Web客户端

    Spring WebFlux还包括一个反应式Web客户端,用于管理REST调用。 默认情况下,使用Reactor-Netty与WebFlux服务器进行通信。

    可以使用静态工厂方法或通过其构建器方法(更多的自定义)来创建WebFlux客户端对象。

    静态工厂方法是WebClient.create()WebClient.create(String baseUrl) 。 另一方面, WebClient.builder提供以下选项以向Web客户端对象添加更多详细信息:

    • uriBuilderFactory
    • defaultHeader
    • defaultCookie
    • defaultRequest
    • filter
    • exchangeStrategies
    • clientConnector

    我们将在构建演示应用程序的进行部分中对此进行仔细研究。

    演示申请

    我们将使用WebFlux的标准组件创建一个简单的反应式REST API,它将用作反应式服务器。 然后,将构建一个反应式Web客户端应用程序,该应用程序从该服务器检索信息并处理数据。

    WebFlux Web服务器

    资料库

    首先,通过创建反应式存储库接口为反应式应用程序奠定基础。

     public interface ResourceRepository extends ReactiveCrudRepository<Resource, String> {
    } 

    我们从WebFlux的ReactiveCrudRepository扩展了存储库,该存储库将根据MonoFlux数据类型返回数据,具体取决于可以检索的元素数。

    要将MongoDB与Spring WebFlux结合使用,我们将添加一个配置类,该类告诉Spring应该将数据库作为反应性组件进行处理:

     @EnableReactiveMongoRepositories 
    public class MongoDbConfiguration extends AbstractReactiveMongoConfiguration { 
      @Override 
      public MongoClient reactiveMongoClient() { 
         return MongoClients.create(); 
      } 
      @Override 
      protected String getDatabaseName() { 
        return "testDatabase";
     } 
    } 

    控制者

    完成并配置数据层后,让我们创建一个简单的REST控制器,该控制器将通过GET请求检索MonoFlux资源:

      @RestController 
     @RequestMapping("/resource")
     public class ResourceController { 
     @Autowired 
     ResourceRepository resourceRepository;
     @GetMapping("/{id}")
     public Mono<Resource> getResource(@PathVariable String id) { 
         return resourceRepository.findById(id); 
     } 
     @GetMapping 
     public Flux<Resource> getResources() {
        return resourceRepository.findAll(); 
     } 
    } 

    在这里,我们使用反应式ResourceRepository来查找来自请求的id的资源。 由于我们正在寻找唯一的ID,因此预期结果是1条记录(找到带有传递ID的资源)或0条记录(数据库中没有记录),因此将Mono用作返回类型。

    由于findAll()可以返回一个以上的资源元素(如果存在),因此将Flux用作返回类型。

    WebFlux Web客户端

    现在我们已经建立了一个基本的REST应用程序,让我们创建一个Spring WebFlux客户端,该客户端可以将请求发送到WebFlux REST应用程序。

    要启动Web客户端,我们需要使用服务器URL创建一个WebClient对象:

     public WebClient openConnection(String url) {
     client = WebClient.create(url); 
     return client;
    } 

    创建WebClient对象后,我们可以使用它向Web服务器发出请求。

    让我们向服务器发出请求,以给定ID检索资源:

     public void getResourceById(String id) { 
       Mono<Resource> result = client.get() 
       .uri("/resource/{id}", "1") .retrieve() 
       .bodyToMono(Resource.class); 
       result.subscribe(System.out::println);
    } 

    bodyToMono()方法负责将响应的正文包装到Mono 。

    同样,如果调用端点将数据返回为Flux则可以使用以下方法检索它:

     public void getAllResources() 
    { 
     Flux<Resource> result = client.get() 
     .uri("/resource") 
     .retrieve() 
     .bodyToFlux(Resource.class); 
      result.subscribe(System.out::println);
    } 

    结论

    Spring框架允许开发人员使用Spring的WebFlux堆栈制作反应性,非阻塞的应用程序和API。 WebFlux提供的注释与经典Spring MVC应用程序中使用的注释非常相似,这使开发人员可以更轻松地过渡到反应式代码。

    在本指南中,我们介绍了WebFlux框架的最重要概念,并构建了一个演示应用程序以在实践中展示它们。

  • 相关阅读:
    使用 requests 维持会话
    使用 requests 发送 POST 请求
    使用 requests 发送 GET 请求
    requests 安装
    使用 urllib 分析 Robots 协议
    使用 urllib 解析 URL 链接
    使用 urllib 处理 HTTP 异常
    使用 urllib 处理 Cookies 信息
    使用 urllib 设置代理服务
    按单生产程序发布
  • 原文地址:https://www.cnblogs.com/mscm/p/13082915.html
Copyright © 2011-2022 走看看