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

Spring Boot + WebFlux 全面使用實踐指南

 更新時間:2026年01月19日 10:45:20   作者:誰在黃金彼岸  
SpringWebFlux是Spring Framework 5+提供的響應式Web框架,性能與配置優(yōu)化包括調(diào)整Netty參數(shù)、啟用背壓控制和監(jiān)控指標,常見陷阱與最佳實踐,本文給大家介紹Spring Boot+WebFlux全面使用指南,感興趣的朋友跟隨小編一起看看吧

一、什么是 Spring WebFlux?

  • 定位:Spring Framework 5+ 提供的 響應式 Web 框架,與 Spring MVC 并列;
  • 核心目標:支持 非阻塞、異步、事件驅(qū)動 的高并發(fā) Web 應用;
  • 底層依賴
    • 響應式流規(guī)范(Reactive Streams)
    • Project Reactor(Mono / Flux
    • 非阻塞服務器(默認 Netty,也支持 Undertow、Servlet 3.1+ 容器)

? WebFlux ≠ WebMVC 替代品,而是 互補技術(shù)棧,適用于不同場景。

二、何時使用 WebFlux?

場景推薦
高并發(fā) I/O 密集型(API 網(wǎng)關(guān)、實時推送、IoT)? 強烈推薦
全鏈路響應式技術(shù)棧(R2DBC + WebClient + Reactive MQ)?
低并發(fā)傳統(tǒng)業(yè)務系統(tǒng)(后臺管理、簡單 CRUD)? 用 WebMVC 更簡單
強事務性/復雜 SQL(需 Hibernate/JPA)? 不適合

三、快速入門:創(chuàng)建 WebFlux 項目

1. 使用 Spring Initializr(https://start.spring.io/)

選擇:

  • Project: Maven / Gradle
  • Language: Java
  • Spring Boot: 3.x(推薦)
  • Dependencies:
    • Spring Reactive Web
    • Spring Data R2DBC(如需數(shù)據(jù)庫)
    • H2 DatabaseMariaDB Driver(根據(jù)需要)

2. 手動添加依賴(Maven)

<dependencies>
    <!-- WebFlux 核心 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <!-- 響應式數(shù)據(jù)庫(以 MariaDB 為例) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-r2dbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mariadb</groupId>
        <artifactId>r2dbc-mariadb</artifactId>
        <version>1.1.5</version>
    </dependency>
    <dependency>
        <groupId>org.mariadb</groupId>
        <artifactId>mariadb-java-client</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- 測試 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.projectreactor</groupId>
        <artifactId>reactor-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

3. 啟動類(無需特殊注解)

@SpringBootApplication
public class WebfluxDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebfluxDemoApplication.class, args);
    }
}

?? 啟動日志將顯示:Netty started on port 8080

四、兩種編程模型

A. 注解式(Annotation-based)— 類似 Spring MVC

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserRepository userRepository;
    // 返回單個對象
    @GetMapping("/{id}")
    public Mono<User> getUser(@PathVariable String id) {
        return userRepository.findById(id);
    }
    // 返回列表流
    @GetMapping
    public Flux<User> getAllUsers() {
        return userRepository.findAll();
    }
    // 創(chuàng)建用戶
    @PostMapping
    public Mono<User> createUser(@RequestBody User user) {
        return userRepository.save(user);
    }
    // SSE:服務器推送事件
    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> streamEvents() {
        return Flux.interval(Duration.ofSeconds(1))
                   .map(seq -> "Event #" + seq);
    }
}

? 優(yōu)點:學習成本低,與 MVC 風格一致
?? 注意:方法必須返回 MonoFlux

B. 函數(shù)式(Functional)— 純函數(shù)式路由

1. 定義 Handler

@Component
public class UserHandler {
    private final UserRepository userRepository;
    public UserHandler(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public Mono<ServerResponse> getUser(ServerRequest request) {
        String id = request.pathVariable("id");
        Mono<User> user = userRepository.findById(id);
        return user
            .flatMap(u -> ServerResponse.ok().bodyValue(u))
            .switchIfEmpty(ServerResponse.notFound().build());
    }
    public Mono<ServerResponse> getAllUsers(ServerRequest request) {
        Flux<User> users = userRepository.findAll();
        return ServerResponse.ok().body(users, User.class);
    }
}

2. 定義 RouterFunction(替代 @RequestMapping)

@Configuration
public class UserRouter {
    @Bean
    public RouterFunction<ServerResponse> userRoutes(UserHandler handler) {
        return route()
            .GET("/users/{id}", handler::getUser)
            .GET("/users", handler::getAllUsers)
            .build();
    }
}

? 優(yōu)點:更符合響應式思想,易于單元測試,無反射開銷
?? 適合構(gòu)建輕量級、高內(nèi)聚的 API

五、響應式數(shù)據(jù)訪問(R2DBC)

1. 實體類

@Table("users")
public class User {
    @Id
    private Long id;
    private String name;
    private String email;
    // constructors, getters, setters
}

2. Repository

public interface UserRepository extends ReactiveCrudRepository<User, Long> {
    Flux<User> findByEmail(String email);
}

3. application.yml 配置

spring:
  r2dbc:
    url: r2dbc:mariadb://localhost:3306/mydb
    username: root
    password: password

支持連接池(需引入 io.r2dbc:r2dbc-pool

六、響應式 HTTP 客戶端:WebClient

替代 RestTemplate,非阻塞調(diào)用外部服務:

@Service
public class ExternalServiceClient {
    private final WebClient webClient;
    public ExternalServiceClient() {
        this.webClient = WebClient.builder()
            .baseUrl("https://api.example.com")
            .build();
    }
    public Mono<UserProfile> fetchProfile(String userId) {
        return webClient.get()
            .uri("/profiles/{id}", userId)
            .retrieve()
            .bodyToMono(UserProfile.class)
            .onErrorResume(e -> Mono.empty()); // 錯誤降級
    }
}

七、全局異常處理

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(UserNotFoundException.class)
    public Mono<ResponseEntity<String>> handleUserNotFound(Exception ex) {
        return Mono.just(ResponseEntity
            .status(HttpStatus.NOT_FOUND)
            .body("User not found"));
    }
    @ExceptionHandler(Exception.class)
    public Mono<ResponseEntity<String>> handleGeneral(Exception ex) {
        return Mono.just(ResponseEntity
            .status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body("Internal error"));
    }
}

也可使用函數(shù)式方式注冊 WebExceptionHandler。

八、測試:WebTestClient

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerTest {
    @Autowired
    private WebTestClient webClient;
    @Test
    void shouldGetUser() {
        webClient.get().uri("/users/1")
            .exchange()
            .expectStatus().isOk()
            .expectBody(User.class)
            .value(user -> assertThat(user.getName()).isEqualTo("Alice"));
    }
}

九、性能與配置優(yōu)化

1. 調(diào)整 Netty 參數(shù)(application.yml)

server:
  netty:
    connection-timeout: 30s
    max-in-memory-size: 10MB  # 防止 OOM

2. 啟用背壓控制

Flux.range(1, 1000)
    .limitRate(100) // 控制上游發(fā)射速率
    .onBackpressureBuffer(500); // 緩沖溢出數(shù)據(jù)

3. 監(jiān)控與指標

集成 Micrometer + Prometheus,監(jiān)控 reactor.netty.connection.provider.active.connections 等指標。

十、常見陷阱與最佳實踐

問題建議
在 WebFlux 中調(diào)用 JDBC / Thread.sleep()? 會阻塞 EventLoop,導致服務不可用
混合使用 WebMVC 和 WebFlux?? 可以共存,但不要在同一個 Controller 中混用
忽略背壓?? 大流量下可能 OOM,務必使用 limitRate / onBackpressureXXX
過度使用 block()? 破壞響應式模型,僅用于測試或邊界轉(zhuǎn)換

? 總結(jié):WebFlux 開發(fā) Checklist

  • 使用 spring-boot-starter-webflux
  • 返回類型為 Mono<T>Flux<T>
  • 數(shù)據(jù)庫使用 R2DBC(非 JDBC)
  • HTTP 調(diào)用使用 WebClient
  • 避免任何阻塞操作
  • 使用 WebTestClient 測試
  • 合理處理背壓和錯誤

通過以上指南,你已掌握 Spring Boot + WebFlux 的完整開發(fā)能力。記?。?strong>WebFlux 的價值不在于“更快”,而在于“更高吞吐、更低資源消耗”。在合適的場景下使用它,將顯著提升系統(tǒng)伸縮性。

官方文檔:

到此這篇關(guān)于Spring Boot + WebFlux 全面使用實踐指南的文章就介紹到這了,更多相關(guān)Spring Boot WebFlux使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot 中 @Scheduled 定時任務不生效的原因及解決方法

    Spring Boot 中 @Scheduled 定時任務不生效的原因及解決方法

    SpringBoot中@Scheduled注解用于創(chuàng)建定時任務,但有時任務可能不生效,本文介紹Spring Boot 中 @Scheduled 定時任務不生效的原因及解決方法,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • Java 面試題和答案 - (下)

    Java 面試題和答案 - (下)

    本文主要介紹Java 面試題,這里整理了Java面試題關(guān)于JDBC,線程異常處理,Servlet,JSP的知識的整理,幫助大家理解知識點,便于面試,有興趣的小伙伴可以參考下
    2016-09-09
  • 從零開始SSM搭建步驟(圖文)

    從零開始SSM搭建步驟(圖文)

    這篇文章主要介紹了從零開始SSM搭建步驟(圖文),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • Java線程編程中isAlive()和join()的使用詳解

    Java線程編程中isAlive()和join()的使用詳解

    這篇文章主要介紹了Java線程編程中isAlive()和join()的使用詳解,是Java入門學習中的基礎知識,需要的朋友可以參考下
    2015-09-09
  • JAVA實現(xiàn)圖書管理系統(tǒng)項目

    JAVA實現(xiàn)圖書管理系統(tǒng)項目

    相信每一個學生學編程的時候,應該都會寫一個小項目——圖書管理系統(tǒng)。為什么這么說呢?我認為一個學校的氛圍很大一部分可以從圖書館的氛圍看出來,而圖書管理系統(tǒng)這個不大不小的項目,接觸的多,也比較熟悉,不會有陌生感,能夠練手,又有些難度,所以我的小項目也來了
    2021-10-10
  • 解決StringBuffer和StringBuilder的擴容問題

    解決StringBuffer和StringBuilder的擴容問題

    這篇文章主要介紹了解決StringBuffer和StringBuilder的擴容問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring IOC簡單理解及創(chuàng)建對象的方式

    Spring IOC簡單理解及創(chuàng)建對象的方式

    這篇文章主要介紹了Spring IOC簡單理解及創(chuàng)建對象的方式,本文通過兩種方式給大家介紹創(chuàng)建對象的方法,通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • Java內(nèi)存分配多種情況的用法解析

    Java內(nèi)存分配多種情況的用法解析

    這篇文章主要介紹了Java內(nèi)存分配多種情況的用法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • 關(guān)于SpringBoot整合redis使用Lettuce客戶端超時問題

    關(guān)于SpringBoot整合redis使用Lettuce客戶端超時問題

    使用到Lettuce連接redis,一段時間后不操作,再去操作redis,會報連接超時錯誤,在其重連后又可使用,糾結(jié)是什么原因?qū)е碌哪兀旅嫘【幗o大家?guī)砹薙pringBoot整合redis使用Lettuce客戶端超時問題及解決方案,一起看看吧
    2021-08-08
  • Java日期類詳解(最新推薦)

    Java日期類詳解(最新推薦)

    早期版本主要使用?java.util.Date、java.util.Calendar?等類,Java?8及以后引入了新的日期和時間API(JSR?310),包含在java.time包中,本文給大家介紹Java日期類的相關(guān)知識,感興趣的朋友一起看看吧
    2025-06-06

最新評論

方山县| 浮山县| 屏山县| 荥阳市| 芦山县| 临武县| 大渡口区| 刚察县| 龙陵县| 唐山市| 台南县| 丰镇市| 丰顺县| 卢龙县| 乌拉特中旗| 丰原市| 大冶市| 中卫市| 富锦市| 师宗县| 历史| 色达县| 苏尼特左旗| 福清市| 苏尼特左旗| 丘北县| 且末县| 海林市| 密山市| 安达市| 苗栗市| 广河县| 墨脱县| 遂宁市| 施秉县| 玛多县| 梁河县| 齐齐哈尔市| 石狮市| 永济市| 宁夏|