<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Spring WebFlux 2025 構建高性能非阻塞API

      在現代分布式系統中,高并發場景越來越普遍,傳統的阻塞式IO模型已難以滿足需求。Spring WebFlux作為Spring生態中的響應式編程解決方案,經過多年發展已成為構建高性能非阻塞API的首選框架。本文將基于2025年最新技術棧,提供一套完整的Spring WebFlux實操指南。

      技術棧準備

      我們將使用以下最新技術組件:

      • Spring Boot 3.3.0(包含Spring WebFlux 6.2.0)
      • Reactor Core 3.6.0(響應式編程基礎)
      • Spring Data R2DBC 3.3.0(關系型數據庫響應式訪問)
      • H2 Database 2.3.0(嵌入式數據庫,方便演示)
      • Project Reactor Addons 3.6.0(響應式工具類)
      • Java 21(提供虛擬線程等新特性)

      環境搭建

      首先創建一個Spring Boot項目,推薦使用Spring Initializr(https://start.spring.io/),選擇以下依賴:

      • Spring Reactive Web
      • Spring Data R2DBC
      • H2 Database
      • Lombok(可選,簡化代碼)

      Maven依賴文件(pom.xml)關鍵部分如下:

      <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>3.3.0</version>
          <relativePath/>
      </parent>
      
      <dependencies>
          <!-- Spring WebFlux 核心依賴 -->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-webflux</artifactId>
          </dependency>
      
          <!-- 響應式數據庫支持 -->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-data-r2dbc</artifactId>
          </dependency>
      
          <!-- H2 數據庫 -->
          <dependency>
              <groupId>com.h2database</groupId>
              <artifactId>h2</artifactId>
              <scope>runtime</scope>
          </dependency>
      
          <!-- 響應式工具類 -->
          <dependency>
              <groupId>io.projectreactor.addons</groupId>
              <artifactId>reactor-extra</artifactId>
          </dependency>
      
          <!-- Lombok 簡化代碼 -->
          <dependency>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
              <optional>true</optional>
          </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>
      </dependencies>
       
       

      項目結構設計

      我們將構建一個簡單的用戶管理API,采用分層架構:

      com.example.reactive
      ├── config          # 配置類
      ├── controller      # 控制器層
      ├── handler         # 函數式處理器
      ├── router          # 路由配置
      ├── model           # 數據模型
      ├── repository      # 數據訪問層
      └── service         # 業務邏輯層
       
       

      核心代碼實現

      1. 數據模型

      首先創建用戶實體類:

      package com.example.reactive.model;
      
      import lombok.AllArgsConstructor;
      import lombok.Data;
      import lombok.NoArgsConstructor;
      import org.springframework.data.annotation.Id;
      import org.springframework.data.relational.core.mapping.Table;
      
      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      @Table("users")
      public class User {
         
          @Id
          private Long id;
          private String username;
          private String email;
          private String fullName;
          private boolean active;
      }
       
       

      2. 數據庫配置

      創建R2DBC配置類,配置數據庫連接:

      package com.example.reactive.config;
      
      import io.r2dbc.h2.H2ConnectionFactory;
      import io.r2dbc.spi.ConnectionFactory;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration;
      import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
      
      @Configuration
      @EnableR2dbcRepositories(basePackages = "com.example.reactive.repository")
      public class R2DBCConfig extends AbstractR2dbcConfiguration {
         
      
          @Bean
          @Override
          public ConnectionFactory connectionFactory() {
         
              // 使用內存模式的H2數據庫
              return H2ConnectionFactory.inMemory("testdb");
          }
      }
       
       

      創建數據庫初始化腳本(src/main/resources/schema.sql):

      CREATE TABLE IF NOT EXISTS users (
          id BIGINT AUTO_INCREMENT PRIMARY KEY,
          username VARCHAR(50) NOT NULL UNIQUE,
          email VARCHAR(100) NOT NULL UNIQUE,
          full_name VARCHAR(100) NOT NULL,
          active BOOLEAN DEFAULT TRUE
      );
       
       

      3. 數據訪問層

      創建響應式Repository接口:

      package com.example.reactive.repository;
      
      import com.example.reactive.model.User;
      import org.springframework.data.r2dbc.repository.R2dbcRepository;
      import org.springframework.stereotype.Repository;
      import reactor.core.publisher.Mono;
      
      @Repository
      public interface UserRepository extends R2dbcRepository<User, Long> {
         
          // 根據用戶名查詢用戶
          Mono<User> findByUsername(String username);
      
          // 根據郵箱查詢用戶
          Mono<User> findByEmail(String email);
      }
       
       

      4. 業務邏輯層

      創建服務接口和實現類:

      package com.example.reactive.service;
      
      import com.example.reactive.model.User;
      import reactor.core.publisher.Flux;
      import reactor.core.publisher.Mono;
      
      public interface UserService {
         
          Flux<User> findAll();
          Mono<User> findById(Long id);
          Mono<User> save(User user);
          Mono<User> update(Long id, User user);
          Mono<Void> deleteById(Long id);
          Mono<User> findByUsername(String username);
      }
       
       

      實現類:

      package com.example.reactive.service;
      
      import com.example.reactive.model.User;
      import com.example.reactive.repository.UserRepository;
      import lombok.RequiredArgsConstructor;
      import org.springframework.stereotype.Service;
      import reactor.core.publisher.Flux;
      import reactor.core.publisher.Mono;
      
      @Service
      @RequiredArgsConstructor
      public class UserServiceImpl implements UserService {
         
      
          private final UserRepository userRepository;
      
          @Override
          public Flux<User> findAll() {
         
              return userRepository.findAll();
          }
      
          @Override
          public Mono<User> findById(Long id) {
         
              return userRepository.findById(id)
                      .switchIfEmpty(Mono.error(new RuntimeException("User not found with id: " + id)));
          }
      
          @Override
          public Mono<User> save(User user) {
         
              // 可以在這里添加業務驗證邏輯
              return userRepository.save(user);
          }
      
          @Override
          public Mono<User> update(Long id, User user) {
         
              return userRepository.findById(id)
                      .flatMap(existingUser -> {
         
                          existingUser.setUsername(user.getUsername());
                          existingUser.setEmail(user.getEmail());
                          existingUser.setFullName(user.getFullName());
                          existingUser.setActive(user.isActive());
                          return userRepository.save(existingUser);
                      })
                      .switchIfEmpty(Mono.error(new RuntimeException("User not found with id: " + id)));
          }
      
          @Override
          public Mono<Void> deleteById(Long id) {
         
              return userRepository.existsById(id)
                      .flatMap(exists -> {
         
                          if (exists) {
         
                              return userRepository.deleteById(id);
                          } else {
         
                              return Mono.error(new RuntimeException("User not found with id: " + id));
                          }
                      });
          }
      
          @Override
          public Mono<User> findByUsername(String username) {
         
              return userRepository.findByUsername(username)
                      .switchIfEmpty(Mono.error(new RuntimeException("User not found with username: " + username)));
          }
      }
       
       

      5. API實現(注解式控制器)

      創建基于注解的REST控制器:

      package com.example.reactive.controller;
      
      import com.example.reactive.model.User;
      import com.example.reactive.service.UserService;
      import lombok.RequiredArgsConstructor;
      import org.springframework.http.HttpStatus;
      import org.springframework.http.ResponseEntity;
      import org.springframework.web.bind.annotation.*;
      import reactor.core.publisher.Flux;
      import reactor.core.publisher.Mono;
      
      @RestController
      @RequestMapping("/api/users")
      @RequiredArgsConstructor
      public class UserController {
         
      
          private final UserService userService;
      
          @GetMapping
          public Flux<User> getAllUsers() {
         
              return userService.findAll();
          }
      
          @GetMapping("/{id}")
          public Mono<ResponseEntity<User>> getUserById(@PathVariable Long id) {
         
              return userService.findById(id)
                      .map(ResponseEntity::ok)
                      .defaultIfEmpty(ResponseEntity.notFound().build());
          }
      
          @GetMapping("/username/{username}")
          public Mono<ResponseEntity<User>> getUserByUsername(@PathVariable String username) {
         
              return userService.findByUsername(username)
                      .map(ResponseEntity::ok)
                      .defaultIfEmpty(ResponseEntity.notFound().build());
          }
      
          @PostMapping
          @ResponseStatus(HttpStatus.CREATED)
          public Mono<User> createUser(@RequestBody User user) {
         
              return userService.save(user);
          }
      
          @PutMapping("/{id}")
          public Mono<ResponseEntity<User>> updateUser(@PathVariable Long id, @RequestBody User user) {
         
              return userService.update(id, user)
                      .map(ResponseEntity::ok)
                      .defaultIfEmpty(ResponseEntity.notFound().build());
          }
      
          @DeleteMapping("/{id}")
          public Mono<ResponseEntity<Void>> deleteUser(@PathVariable Long id) {
         
              return userService.deleteById(id)
                      .then(Mono.just(ResponseEntity.noContent().build()))
                      .onErrorResume(e -> Mono.just(ResponseEntity.notFound().build()));
          }
      
          // 全局異常處理
          @ExceptionHandler(RuntimeException.class)
          public ResponseEntity<String> handleRuntimeException(RuntimeException ex) {
         
              return ResponseEntity
                      .status(HttpStatus.NOT_FOUND)
                      .body(ex.getMessage());
          }
      }
       
       

      6. API實現(函數式端點)

      除了注解式控制器,Spring WebFlux還支持函數式編程模型。下面實現一套相同功能的函數式端點:

      首先創建處理器:

      package com.example.reactive.handler;
      
      import com.example.reactive.model.User;
      import com.example.reactive.service.UserService;
      import lombok.RequiredArgsConstructor;
      import org.springframework.http.HttpStatus;
      import org.springframework.http.MediaType;
      import org.springframework.stereotype.Component;
      import org.springframework.web.reactive.function.server.ServerRequest;
      import org.springframework.web.reactive.function.server.ServerResponse;
      import reactor.core.publisher.Mono;
      
      @Component
      @RequiredArgsConstructor
      public class UserHandler {
         
      
          private final UserService userService;
      
          // 獲取所有用戶
          public Mono<ServerResponse> getAllUsers(ServerRequest request) {
         
              return ServerResponse.ok()
                      .contentType(MediaType.APPLICATION_JSON)
                      .body(userService.findAll(), User.class);
          }
      
          // 根據ID獲取用戶
          public Mono<ServerResponse> getUserById(ServerRequest request) {
         
              Long id = Long.parseLong(request.pathVariable("id"));
      
              return userService.findById(id)
                      .flatMap(user -> ServerResponse.ok()
                              .contentType(MediaType.APPLICATION_JSON)
                              .bodyValue(user))
                      .switchIfEmpty(ServerResponse.notFound().build());
          }
      
          // 創建用戶
          public Mono<ServerResponse> createUser(ServerRequest request) {
         
              Mono<User> userMono = request.bodyToMono(User.class);
      
              return userMono
                      .flatMap(user -> userService.save(user))
                      .flatMap(savedUser -> ServerResponse.status(HttpStatus.CREATED)
                              .contentType(MediaType.APPLICATION_JSON)
                              .bodyValue(savedUser));
          }
      
          // 更新用戶
          public Mono<ServerResponse> updateUser(ServerRequest request) {
         
              Long id = Long.parseLong(request.pathVariable("id"));
              Mono<User> userMono = request.bodyToMono(User.class);
      
              return userMono
                      .flatMap(user -> userService.update(id, user))
                      .flatMap(updatedUser -> ServerResponse.ok()
                              .contentType(MediaType.APPLICATION_JSON)
                              .bodyValue(updatedUser))
                      .switchIfEmpty(ServerResponse.notFound().build());
          }
      
          // 刪除用戶
          public Mono<ServerResponse> deleteUser(ServerRequest request) {
         
              Long id = Long.parseLong(request.pathVariable("id"));
      
              return userService.deleteById(id)
                      .then(ServerResponse.noContent().build())
                      .onErrorResume(e -> ServerResponse.notFound().build());
          }
      }
       
       

      然后創建路由配置:

      package com.example.reactive.router;
      
      import com.example.reactive.handler.UserHandler;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.reactive.function.server.RouterFunction;
      import org.springframework.web.reactive.function.server.RouterFunctions;
      import org.springframework.web.reactive.function.server.ServerResponse;
      
      import static org.springframework.web.reactive.function.server.RequestPredicates.*;
      
      @Configuration
      public class UserRouter {
         
      
          @Bean
          public RouterFunction<ServerResponse> userRoutes(UserHandler userHandler) {
         
              return RouterFunctions
                      .route(GET("/func/users"), userHandler::getAllUsers)
                      .andRoute(GET("/func/users/{id}"), userHandler::getUserById)
                      .andRoute(POST("/func/users"), userHandler::createUser)
                      .andRoute(PUT("/func/users/{id}"), userHandler::updateUser)
                      .andRoute(DELETE("/func/users/{id}"), userHandler::deleteUser);
          }
      }
       
       

      響應式客戶端使用

      Spring WebFlux提供了WebClient作為響應式HTTP客戶端,下面演示如何使用它:

      package com.example.reactive.service;
      
      import com.example.reactive.model.User;
      import lombok.RequiredArgsConstructor;
      import org.springframework.stereotype.Component;
      import org.springframework.web.reactive.function.client.WebClient;
      import reactor.core.publisher.Flux;
      import reactor.core.publisher.Mono;
      
      @Component
      @RequiredArgsConstructor
      public class UserWebClient {
         
      
          private final WebClient webClient;
      
          // 構造函數注入WebClient
          public UserWebClient() {
         
              this.webClient = WebClient.create("http://localhost:8080");
          }
      
          // 獲取所有用戶
          public Flux<User> getAllUsers() {
         
              return webClient.get()
                      .uri("/api/users")
                      .retrieve()
                      .bodyToFlux(User.class);
          }
      
          // 根據ID獲取用戶
          public Mono<User> getUserById(Long id) {
         
              return webClient.get()
                      .uri("/api/users/{id}", id)
                      .retrieve()
                      .bodyToMono(User.class);
          }
      
          // 創建用戶
          public Mono<User> createUser(User user) {
         
              return webClient.post()
                      .uri("/api/users")
                      .bodyValue(user)
                      .retrieve()
                      .bodyToMono(User.class);
          }
      }
       
       

      測試響應式API

      使用JUnit 5和Reactor Test進行測試:

      package com.example.reactive.controller;
      
      import com.example.reactive.model.User;
      import com.example.reactive.service.UserService;
      import org.junit.jupiter.api.Test;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
      import org.springframework.boot.test.mock.mockito.MockBean;
      import org.springframework.http.MediaType;
      import org.springframework.test.web.reactive.server.WebTestClient;
      import reactor.core.publisher.Flux;
      import reactor.core.publisher.Mono;
      
      import static org.mockito.ArgumentMatchers.any;
      import static org.mockito.Mockito.when;
      
      @WebFluxTest(UserController.class)
      public class UserControllerTest {
         
      
          @Autowired
          private WebTestClient webTestClient;
      
          @MockBean
          private UserService userService;
      
          @Test
          public void testGetAllUsers() {
         
              User user1 = new User(1L, "user1", "user1@example.com", "User One", true);
              User user2 = new User(2L, "user2", "user2@example.com", "User Two", true);
      
              when(userService.findAll()).thenReturn(Flux.just(user1, user2));
      
              webTestClient.get().uri("/api/users")
                      .accept(MediaType.APPLICATION_JSON)
                      .exchange()
                      .expectStatus().isOk()
                      .expectHeader().contentType(MediaType.APPLICATION_JSON)
                      .expectBodyList(User.class)
                      .hasSize(2)
                      .contains(user1, user2);
          }
      
          @Test
          public void testCreateUser() {
         
              User user = new User(null, "newuser", "newuser@example.com", "New User", true);
              User savedUser = new User(3L, "newuser", "newuser@example.com", "New User", true);
      
              when(userService.save(any(User.class))).thenReturn(Mono.just(savedUser));
      
              webTestClient.post().uri("/api/users")
                      .contentType(MediaType.APPLICATION_JSON)
                      .bodyValue(user)
                      .exchange()
                      .expectStatus().isCreated()
                      .expectBody(User.class)
                      .isEqualTo(savedUser);
          }
      }
       
       

      性能優化建議

      1. 背壓管理:利用Reactor的背壓機制,控制數據流速度,防止下游組件被壓垮

      2. 連接池配置:優化R2DBC連接池和WebClient連接池

        @Bean
        public ConnectionFactory connectionFactory() {
             
            H2ConnectionConfiguration config = H2ConnectionConfiguration.builder()
                    .url("r2dbc:h2:mem:testdb")
                    .username("sa")
                    .password("")
                    .build();
        
            return ConnectionPoolConfiguration.builder()
                    .connectionFactory(new H2ConnectionFactory(config))
                    .maxSize(10)
                    .build();
        }
         
         
      3. 數據批量處理:使用Flux.buffer()Flux.window()進行批量操作

      4. 緩存熱點數據:結合cache()操作符緩存頻繁訪問的數據

      5. 監控與指標:集成Micrometer監控響應式流的性能指標

      總結

      Spring WebFlux提供了構建非阻塞、高性能API的完整解決方案。通過本文的實操指南,你已經了解了如何使用最新的Spring WebFlux技術棧構建響應式API,包括:

      • 環境搭建與配置
      • 響應式數據訪問
      • 兩種API實現方式(注解式和函數式)
      • 響應式客戶端使用
      • 測試與性能優化

      在實際項目中,應根據具體場景選擇合適的編程模型,并充分利用響應式編程的特性來提升系統的并發處理能力和資源利用率。隨著Java和Spring生態的不斷發展,響應式編程將會在高并發場景中發揮越來越重要的作用。

      posted @ 2025-10-27 16:20  kiyte  閱讀(10)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品国产精品无卡区| 永泰县| 日日碰狠狠添天天爽五月婷| 国产在热线精品视频99公交| 国产羞羞的视频一区二区| 中文字幕一区二区三区精彩视频| 国产亚洲精品久久久网站好莱| 国产啪视频免费观看视频| 人人妻人人澡人人爽曰本| 粉嫩一区二区三区国产精品| 人妻夜夜爽天天爽一区| av高清无码 在线播放| 蜜臀人妻精品一区二区免费| 国产亚洲国产精品二区| 徐水县| 丰满的人妻hd高清日本| 国产精品一区免费在线看| 97精品久久九九中文字幕| 无码福利写真片视频在线播放| 日韩在线视频网| 国产精品午夜精品福利| 又黄又爽又色的少妇毛片| 蜜桃久久精品成人无码av| 亚洲一区二区三区18禁| 国内精品伊人久久久久影院对白| 熟女丝袜潮喷内裤视频网站| 五月丁香六月狠狠爱综合 | 亚洲熟女乱色综一区二区| 欧美一区二区三区欧美日韩亚洲| 亚洲男人AV天堂午夜在| 国产互换人妻xxxx69| 亚洲国产精品日韩在线| 久久av无码精品人妻出轨| 中文字幕乱码中文乱码毛片| 国产日韩一区二区天美麻豆| 久久不卡精品| 一卡2卡三卡4卡免费网站| 性男女做视频观看网站| 成人无码午夜在线观看| 国产精品免费看久久久| 亚洲av本道一区二区|