• 【SpringBoot】SpringBoot2.0响应式编程


    ========================15、高级篇幅之SpringBoot2.0响应式编程 ================================

    1、SprinBoot2.x响应式编程简介
    简介:讲解什么是reactive响应式编程和使用的好处

    1、基础理解:
    依赖于事件,事件驱动(Event-driven)
    一系列事件称为“流”
    异步
    非阻塞

    观察者模式

    网上的一个例子:
    int b= 2;
    int c=3
    int a = b+c //命令式编程后续b和c变化,都不影响a
    b=5;

    int b= 2;
    int c= 3
    int a = b+c //响应式编程中,a的变化,会和b、c的变化而变化(事件驱动)
    b=5;

    2、官网:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-webflux
    SpingBoot2底层是用spring5,开始支持响应式编程,Spring又是基于Reactor试下响应式。

    学习资料
    1、reactive-streams学习资料:http://www.reactive-streams.org/
    2、web-flux相关资料:https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux

    2、SpringBoot2.x响应式编程webflux介绍
    简介:讲解SpringBoot2.x响应式编程介绍 Mono、Flux对象和优缺点

    1、Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架
    与Spring MVC不同,它不需要Servlet API,完全异步和非阻塞,并 通过Reactor项目实现Reactive Streams规范。
    RxJava

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

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


    3、Spring WebFlux有两种风格:基于功能和基于注解的。基于注解非常接近Spring MVC模型,如以下示例所示:
    第一种:
    @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){
    // ...
    }

    }
    第二种: 路由配置与请求的实际处理分开
    @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);
    }

    }

    @Component
    public class UserHandler {

    公共 Mono <ServerResponse> getUser(ServerRequest请求){
    // ...
    }

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

    公共 Mono <ServerResponse> deleteUser(ServerRequest请求){
    // ...
    }
    }

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

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


    3、SpringBoot2.x webflux实战
    简介:webflux响应式编程实战

    1、WebFlux中,请求和响应不再是WebMVC中的(Http)ServletRequest和(Http)ServletResponse,而是ServerRequest和ServerResponse

    2、加入依赖,如果同时存在spring-boot-starter-web,则会优先用spring-boot-starter-web
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>

    测试
    localhost:8080/api/v1/user/test

    3、启动方式默认是Netty,8080端口

    package com.example.demo.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import reactor.core.publisher.Mono;
    
    @RestController
    @RequestMapping("/api/v1/user")
    public class UserController {
        @GetMapping("/test")
        public Mono<String> test(){
            return Mono.just("hello xiaod");
        }
    }
    controller

    4、参考:https://spring.io/blog/2016/04/19/understanding-reactive-types

     

    package com.example.demo.service;
    
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.stereotype.Service;
    
    import com.example.demo.domain.User;
    
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    @Service
    public class UserService {
    private static final Map<String, User> dataMap = new HashMap<>();
        
        static{
            dataMap.put("1", new User("1", "小X老师"));
            dataMap.put("2", new User("2", "小D老师"));
            dataMap.put("3", new User("3", "小C老师"));
            dataMap.put("4", new User("4", "小L老师"));
            dataMap.put("5", new User("5", "小A老师"));
            dataMap.put("6", new User("6", "小S老师"));
            dataMap.put("7", new User("7", "小S老师"));
        }
        public Flux<User> list(){
            Collection<User> list=UserService.dataMap.values();
            return Flux.fromIterable(list);
        }
        public Mono<User> getById(final String id){
            return Mono.justOrEmpty(UserService.dataMap.get(id));
        }
        public Mono<User> del(final String id){
            return Mono.justOrEmpty(UserService.dataMap.remove(id));
        }
        
    }
    service
    package com.example.demo.controller;
    
    import java.time.Duration;
    
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.example.demo.domain.User;
    import com.example.demo.service.UserService;
    
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    @RestController
    @RequestMapping("/api/v1/user")
    public class UserController {
         private UserService userService;
    
    
        public UserController(final UserService userService) {
            this.userService = userService;
        }
        
        
        @GetMapping("/test")
        public Mono<String> test(){
            return Mono.just("hello xiaod");
        }
        @GetMapping("find")
        public Mono<User> findByid(final String id){
            return userService.getById(id);
        }
        
        
        /**
         * 功能描述:删除用户
         * @param id
         * @return
         */
        @GetMapping("del")
        public Mono<User> del(final String id){
            return userService.del(id);
        }
        @GetMapping(value="list",produces=MediaType.APPLICATION_STREAM_JSON_VALUE)
        public Flux<User> list(){
            return userService.list().delayElements(Duration.ofSeconds(2));
        }
    }
    controller

    可以用于服务推送


    4、WebFlux客户端WebClient讲解
    简介:讲解SpringBoot2.x WebFlux客户端WebClient的介绍和使用
    1、反应式客户端

    官网地址:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-webclient

  • 相关阅读:
    linux svn切换用户
    解决QQ“抱歉,无法发起临时会话,您可以 添加对方为好友以发送消息”
    node.js中http.respone.end方法概述
    niginx:duplicate MIME type "text/html" in nginx.conf 错误(转载)
    大三暑假实习,我们可以怎么做
    一个Java程序员的实习总结(2)
    正式工作的前奏——一个Java程序员的实习总结(1)
    【个人】当我秀智商的时候我秀什么
    基于java的设计模式入门(1)——为什么要学习设计模式
    【个人】我不愿让你一个人
  • 原文地址:https://www.cnblogs.com/hellowq/p/10571499.html
Copyright © 2020-2023  润新知