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框架的最重要概念,并构建了一个演示应用程序以在实践中展示它们。

  • 相关阅读:
    Sql Server--如何自动备份数据
    Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Chinese_PRC_CI_AI" in the equal to operation.
    GET方法和POST方法的区别,Get方法到底可传递的字符串的最大长度是多少?
    Specialization For SCCM
    Fullscreen API:全屏操作
    How to enable remote connections to SQL Server
    Advanced Installer
    ajax跨域请求webservice webconfig配置
    SharePoint Resize app
    Sharepoint 开启App 配置App
  • 原文地址:https://www.cnblogs.com/mscm/p/13082915.html
Copyright © 2011-2022 走看看