最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring零基礎(chǔ)入門WebFlux響應(yīng)式編程

 更新時間:2022年10月17日 09:27:20   作者:一根頭發(fā)學一年  
Spring 提供了兩個并行堆棧,一種是基于帶有 Spring MVC 和 Spring Data 結(jié)構(gòu)的 Servlet API,另一個是完全反應(yīng)式堆棧,它利用了 Spring WebFlux 和 Spring Data 的反應(yīng)式存儲庫,這篇文章主要介紹了Spring-webflux 響應(yīng)式編程,需要的朋友可以參考下

說明:基于atguigu學習筆記。

簡介

Webflux是 Spring5 添加新的模塊,用于 web 開發(fā)的,功能和 SpringMVC 類似的,Webflux 使用當前一種比較流程響應(yīng)式編程出現(xiàn)的框架。

使用傳統(tǒng) web 框架,比如 SpringMVC,這些基于 Servlet 容器,Webflux 是一種異步非阻

塞的框架,異步非阻塞的框架在 Servlet3.1 以后才支持,核心是基于 Reactor 的相關(guān) API 實現(xiàn)

的。

Webflux 特點:

  • 非阻塞式:在有限資源下,提高系統(tǒng)吞吐量和伸縮性,以 Reactor 為基礎(chǔ)實現(xiàn)響應(yīng)式編程
  • 函數(shù)式編程:Spring5 框架基于 java8,Webflux 使用 Java8 函數(shù)式編程方式實現(xiàn)路由請求

比較 SpringMVC:

第一:兩個框架都可以使用注解方式,都運行在 Tomet 等容器中

第二:SpringMVC 采用命令式編程,Webflux 采用異步響應(yīng)式編程

響應(yīng)式編程

響應(yīng)式編程是一種面向數(shù)據(jù)流和變化傳播的編程范式。這意味著可以在編程語言中很方便地表達靜態(tài)或動態(tài)的數(shù)據(jù)流,而相關(guān)的計算模型會自動將變化的值通過數(shù)據(jù)流進行傳播。電子表格程序就是響應(yīng)式編程的一個例子。單元格可以包含字面值或類似"=B1+C1"的公式,而包含公式的單元格的值會依據(jù)其他單元格的值的變化而變化

Reactor

Reactor 框架是 Pivotal 基于 Reactive Programming 思想實現(xiàn)的。

Reactor 有兩個核心類,Mono 和 Flux,這兩個類實現(xiàn)接口 Publisher,提供豐富操作

符。Flux 對象實現(xiàn)發(fā)布者,返回 N 個元素;Mono 實現(xiàn)發(fā)布者,返回 0 或者 1 個元素。

信號

Flux 和 Mono 都是數(shù)據(jù)流的發(fā)布者,使用 Flux 和 Mono 都可以發(fā)出三種數(shù)據(jù)信號:

元素值,錯誤信號,完成信號,錯誤信號和完成信號都代表終止信號,終止信號用于告訴

訂閱者數(shù)據(jù)流結(jié)束了,錯誤信號終止數(shù)據(jù)流同時把錯誤信息傳遞給訂閱者。

示例:

1.引入依賴

<dependency> 
	<groupId>io.projectreactor</groupId> 
	<artifactId>reactor-core</artifactId> 
	<version>3.1.5.RELEASE</version>
</dependency>

2.代碼

package com.example.springdemo3;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Test01 {
    public static void main(String[] args) {
        //just 方法直接聲明
        Flux.just(1,2,3,4);
        Mono.just(1);
        //其他的方法
        Integer[] array = {1,2,3,4};
        Flux.fromArray(array);
        List<Integer> list = Arrays.asList(array);
        Flux.fromIterable(list);
        Stream<Integer> stream = list.stream();
        Flux.fromStream(stream);
    }
}

三種信號特點

  • 錯誤信號和完成信號都是終止信號,不能共存的
  • 如果沒有發(fā)送任何元素值,而是直接發(fā)送錯誤或者完成信號,表示是空數(shù)據(jù)流
  • 如果沒有錯誤信號,沒有完成信號,表示是無限數(shù)據(jù)流

調(diào)用 just 或者其他方法只是聲明數(shù)據(jù)流,數(shù)據(jù)流并沒有發(fā)出,只有進行訂閱之后才會觸

發(fā)數(shù)據(jù)流,不訂閱什么都不會發(fā)生。示例如下:

package com.example.springdemo3;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Test01 {
    public static void main(String[] args) {
        //just 方法直接聲明
        Flux.just(1,2,3,4).subscribe(System.out::println);
        Mono.just(1).subscribe(System.out::println);;
    }
}

操作符

操作符對數(shù)據(jù)流進行一道道操作,成為操作符,比如工廠流水線。有以下兩個操作符:

1.map

將一個數(shù)據(jù)流里的每個元素映射為新元素,返回一個新的流。

2.flatMap

把每個元素轉(zhuǎn)換成數(shù)據(jù)流,把轉(zhuǎn)換之后多個流合并一個大的數(shù)據(jù)流

SpringWebflux執(zhí)行流程和API

SpringWebflux 基于 Reactor,默認使用容器是 Netty,Netty 是高性能的 NIO 框架,異步非阻

塞的框架。

SpringWebflux 執(zhí)行過程和 SpringMVC 相似的,SpringWebflux 核心控制器 DispatchHandler,實現(xiàn)了接口 WebHandler。WebHandler的源碼如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.web.server;
import reactor.core.publisher.Mono;
public interface WebHandler {
    Mono<Void> handle(ServerWebExchange var1);
}

可以看到只有一個方法WebHandler,WebHandler的實現(xiàn)在DispatcherHandler類中,實現(xiàn)邏輯如下:

public Mono<Void> handle(ServerWebExchange exchange) {
        return this.handlerMappings == null ? this.createNotFoundError() : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
            return mapping.getHandler(exchange);
        }).next().switchIfEmpty(this.createNotFoundError()).flatMap((handler) -> {
            return this.invokeHandler(exchange, handler);
        }).flatMap((result) -> {
            return this.handleResult(exchange, result);
        });
    }

其中,參數(shù)ServerWebExchange是放http請求和響應(yīng)信息;getHandler根據(jù)請求地址獲取對應(yīng)的mapping;invokeHandler調(diào)用具體的業(yè)務(wù)方法;handleResult處理結(jié)果返回。

SpringWebflux 里面 的DispatcherHandler,有3個很重要的屬性,如下:

public class DispatcherHandler implements WebHandler, ApplicationContextAware {
    @Nullable
    private List<HandlerMapping> handlerMappings;
    @Nullable
    private List<HandlerAdapter> handlerAdapters;
    @Nullable
    private List<HandlerResultHandler> resultHandlers;
}

HandlerMapping:請求查詢到處理的方法; HandlerAdapter:真正負責請求處理;HandlerResultHandler:響應(yīng)結(jié)果處理。

SpringWebflux 實現(xiàn)函數(shù)式編程,兩個接口:RouterFunction(路由處理)

和 HandlerFunction(處理函數(shù))。

注解實現(xiàn)SpringWebflux

使用注解編程模型方式,和 SpringMVC 使用相似的,只需要把相關(guān)依賴配置到項目中,

SpringBoot 自動配置相關(guān)運行容器,默認情況下使用 Netty 服務(wù)器。

1.創(chuàng)建項目

創(chuàng)建springboot項目,引入依賴:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>spring-demo3</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-demo3</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.example.springdemo3.SpringDemo3Application</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

2.創(chuàng)建包和相關(guān)類

實體類:

package com.example.springdemo3.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
    private String name;
    private String gender;
    private Integer age;
}

service接口:

package com.example.springdemo3.service;
import com.example.springdemo3.entity.User;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public interface UserService {
    //根據(jù) id 查詢用戶
    Mono<User> getUserById(int id);
    //查詢所有用戶
    Flux<User> getAllUser();
    //添加用戶
    Mono<Void> saveUserInfo(Mono<User> user);
}

service實現(xiàn)類

package com.example.springdemo3.service.impl;
import com.example.springdemo3.entity.User;
import com.example.springdemo3.service.UserService;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
@Service
public class UserServiceImpl implements UserService {
    //創(chuàng)建 map 集合存儲數(shù)據(jù)
    private final Map<Integer,User> users = new HashMap<>();
    public UserServiceImpl() {
        this.users.put(1,new User("lucy","nan",20));
        this.users.put(2,new User("mary","nv",30));
        this.users.put(3,new User("jack","nv",50));
    }
    @Override
    public Mono<User> getUserById(int id) {
        return Mono.justOrEmpty(this.users.get(id));
    }
    @Override
    public Flux<User> getAllUser() {
        return Flux.fromIterable(this.users.values());
    }
    @Override
    public Mono<Void> saveUserInfo(Mono<User> userMono) {
        return userMono.doOnNext(person -> {
            //向 map 集合里面放值
            int id = users.size()+1;
            users.put(id,person);
        }).thenEmpty(Mono.empty()); // Mono.empty()是終止信號
    }
}

注意這里沒有真正和數(shù)據(jù)庫交互,而是維護了一個數(shù)組,模擬數(shù)據(jù)庫。

controller類:

package com.example.springdemo3.controller;
import com.example.springdemo3.entity.User;
import com.example.springdemo3.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Component
@RestController
public class UserController {
    //注入 service
    @Autowired
    private UserService userService;
    //id 查詢
    @GetMapping("/user/{id}")
    public Mono<User> geetUserId(@PathVariable int id) {
        return userService.getUserById(id);
    }
    //查詢所有
    @GetMapping("/user")
    public Flux<User> getUsers() {
        return userService.getAllUser();
    }
    //添加
    @PostMapping("/saveuser")
    public Mono<Void> saveUser(@RequestBody User user) {
        Mono<User> userMono = Mono.just(user);
        return userService.saveUserInfo(userMono);
    }
}

SpringMVC 方式實現(xiàn),同步阻塞的方式,基于 SpringMVC+Servlet+Tomcat

SpringWebflux 方式實現(xiàn),異步非阻塞 方式,基于 SpringWebflux+Reactor+Netty

到此這篇關(guān)于Spring零基礎(chǔ)入門WebFlux響應(yīng)式編程的文章就介紹到這了,更多相關(guān)Spring WebFlux內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis快速入門

    MyBatis快速入門

    MyBatis是支持普通SQL查詢,存儲過程和高級映射的優(yōu)秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數(shù)的手工設(shè)置以及結(jié)果集的檢索。想要學好它,那就要從MyBatis基礎(chǔ)知識學起,下面跟著小編一起來看下吧
    2017-03-03
  • idea 解決用骨架創(chuàng)建項目過慢的操作方式

    idea 解決用骨架創(chuàng)建項目過慢的操作方式

    這篇文章主要介紹了idea 解決用骨架創(chuàng)建項目過慢的操作方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • SpringBoot整合mybatis通用Mapper+自定義通用Mapper方法解析

    SpringBoot整合mybatis通用Mapper+自定義通用Mapper方法解析

    這篇文章主要介紹了SpringBoot整合mybatis通用Mapper+自定義通用Mapper方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • SpringBoot基于MyBatis-Plus實現(xiàn)Lambda Query查詢的示例代碼

    SpringBoot基于MyBatis-Plus實現(xiàn)Lambda Query查詢的示例代碼

    MyBatis-Plus 是 MyBatis 的增強工具,簡化了數(shù)據(jù)庫操作,并提高了開發(fā)效率,它提供了多種查詢方式,包括常規(guī)的 SQL 查詢、Lambda Query 查詢、分頁查詢、條件查詢等,在本篇博客中,我們將詳細講解如何使用 MyBatis-Plus 的各種查詢方式,需要的朋友可以參考下
    2025-01-01
  • idea中如何連接hive

    idea中如何連接hive

    這篇文章主要介紹了idea中如何連接hive問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Java利用策略模式優(yōu)化過多if else代碼

    Java利用策略模式優(yōu)化過多if else代碼

    這篇文章主要介紹了Java利用策略模式優(yōu)化過多if else代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • java實現(xiàn)超大文件的讀寫功能

    java實現(xiàn)超大文件的讀寫功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)超大文件的讀寫功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • 詳解快速搭建Spring Boot+Spring MVC

    詳解快速搭建Spring Boot+Spring MVC

    本篇文章主要介紹了詳解快速搭建Spring Boot+Spring MVC,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • MyBatis中如何優(yōu)雅的使用枚舉詳解

    MyBatis中如何優(yōu)雅的使用枚舉詳解

    枚舉類型是我們在開發(fā)中經(jīng)常遇到的一個類型,最近在學習MyBatis,但是發(fā)現(xiàn)網(wǎng)上沒有詳細介紹MyBatis如何使用枚舉的相關(guān)文章,索性就自己寫一篇,下面這篇文章主要給大家介紹了關(guān)于在MyBatis中如何優(yōu)雅的使用枚舉的相關(guān)資料,需要的朋友可以參考借鑒。
    2017-08-08
  • 通過實例解析java過濾器和攔截器的區(qū)別

    通過實例解析java過濾器和攔截器的區(qū)別

    這篇文章主要介紹了通過實例解析java過濾器和攔截器的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03

最新評論

商丘市| 兴宁市| 景德镇市| 广饶县| 高淳县| 内黄县| 云阳县| 平凉市| 高阳县| 达拉特旗| 米林县| 尼玛县| 治多县| 弥勒县| 和田市| 哈巴河县| 新营市| 宾川县| 兴宁市| 兴城市| 香港| 邯郸市| 宜川县| 泗水县| 铁岭市| 托克逊县| 昌都县| 铜陵市| 墨玉县| 泗水县| 册亨县| 砀山县| 深水埗区| 横峰县| 吴忠市| 恩施市| 保亭| 衡阳县| 蓬溪县| 马边| 海淀区|