您的位置:首頁 > 軟件教程 > 教程 > 深度長文解析SpringWebFlux響應(yīng)式框架15個核心組件源碼

深度長文解析SpringWebFlux響應(yīng)式框架15個核心組件源碼

來源:好特整理 | 時間:2024-07-04 11:48:59 | 閱讀:61 |  標(biāo)簽: Ri 核心 S in   | 分享到:

以上是Spring WebFlux 框架核心組件的全部介紹了,希望可以幫助你全面深入的理解 WebFlux的原理,關(guān)注【威哥愛編程】,主頁里可查看V哥每天更新的原創(chuàng)技術(shù)內(nèi)容,讓我們一起成長。

Spring WebFlux 介紹

Spring WebFlux 是 Spring Framework 5.0 版本引入的一個響應(yīng)式 Web 框架,它與 Spring MVC 并存,提供了一種全新的編程范式,支持異步非阻塞的 Web 應(yīng)用開發(fā)。WebFlux 完全基于響應(yīng)式編程模型,支持 Reactive Streams 規(guī)范,可以在諸如 Netty、Undertow 以及 Servlet 3.1+ 容器上運行。

WebFlux 的核心控制器是 DispatcherHandler,它類似于 Spring MVC 中的 DispatcherServlet,負(fù)責(zé)將請求分發(fā)給相應(yīng)的處理器。DispatcherHandler 通過查找 Spring 配置中的 HandlerMapping、HandlerAdapter 和 HandlerResultHandler 來處理請求。

在 WebFlux 中,F(xiàn)lux 和 Mono 是 Reactor 庫中的兩個基本概念,分別用于表示包含 0 到 N 個元素和 0 或 1 個元素的異步序列。Flux 可以用于表示一個包含多個響應(yīng)式元素的流,而 Mono 用于表示單個元素的響應(yīng)式流。

Spring WebFlux 支持多種編程模式,包括基于注解的控制器和函數(shù)式端點。開發(fā)者可以使用 @RestController 注解來創(chuàng)建響應(yīng)式控制器,并使用 @GetMapping、@PostMapping 等注解來處理 HTTP 請求。同時,WebFlux 也支持使用 WebClient 作為非阻塞的 HTTP 客戶端來與其它服務(wù)進(jìn)行通信。

WebFlux 的并發(fā)模型與傳統(tǒng)的 Spring MVC 有顯著不同。它利用了少量的線程來處理大量的并發(fā)請求,這得益于其非阻塞的特性。當(dāng)運行在 Netty 服務(wù)器上時,WebFlux 使用事件循環(huán)線程來處理請求,避免了傳統(tǒng) Servlet 容器中每個請求都需要一個線程的模型。

Spring WebFlux 的適用場景主要是 IO 密集型的應(yīng)用,例如微服務(wù)網(wǎng)關(guān),它可以顯著提升對下游服務(wù)轉(zhuǎn)發(fā)的吞吐量
。然而,如果現(xiàn)有的 Spring MVC 應(yīng)用能夠滿足性能需求,并且項目中使用了許多基于 Servlet 線程模型的庫,那么可能沒有必要遷移到 WebFlux。

源碼層面,Spring WebFlux 的請求處理流程涉及到多個組件,包括 Netty 服務(wù)器的初始化、請求的接收、DispatcherHandler 的請求分發(fā),以及最終的請求處理和響應(yīng)。在 Netty 服務(wù)器中,請求處理涉及到 ChannelHandler,ConnectionObserver,以及 HttpHandler 等多個組件。這些組件協(xié)同工作,實現(xiàn)了 WebFlux 的非阻塞和響應(yīng)式特性。

Spring WebFlux 都有哪些核心組件

Spring WebFlux 包含多個核心組件,它們共同構(gòu)成了完整的響應(yīng)式 Web 應(yīng)用框架。下面是一些主要的核心組件:

  1. DispatcherHandler:這是 WebFlux 的中央調(diào)度器,類似于 Spring MVC 中的 DispatcherServlet。它負(fù)責(zé)發(fā)現(xiàn)和調(diào)度 HTTP 請求處理器(handlers),并處理請求映射、調(diào)用和結(jié)果處理。

  2. HandlerMapping:這個接口用于將請求映射到對應(yīng)的處理器(handler)。它在應(yīng)用程序上下文中被檢測到,并用于確定請求應(yīng)該由哪個處理器處理。

  3. HandlerAdapter:這個接口幫助 DispatcherHandler 調(diào)用任何類型的處理器,而不需要關(guān)心具體的調(diào)用方式。它為不同的處理器提供了調(diào)用策略。

  4. HandlerResultHandler:這個接口處理處理器調(diào)用后的結(jié)果,并生成最終的響應(yīng)。它負(fù)責(zé)將處理器的結(jié)果轉(zhuǎn)換為客戶端可以接收的格式。

  5. WebFilter:WebFilter 接口定義了一組過濾器,這些過濾器可以對請求和響應(yīng)進(jìn)行預(yù)處理和后處理。

  6. ServerWebExchange:這個類封裝了 HTTP 請求和響應(yīng)的所有信息,例如請求頭、請求體、URI、參數(shù)等。

  7. ServerHttpRequest 和 ServerHttpResponse:這兩個類分別代表服務(wù)器接收的 HTTP 請求和發(fā)送的 HTTP 響應(yīng)。

  8. WebSession:用于管理特定客戶端的會話信息。

  9. Reactive Streams:WebFlux 基于 Reactive Streams 規(guī)范,使用非阻塞背壓機(jī)制來處理數(shù)據(jù)流。

  10. Reactor 庫:作為 Spring 5 的反應(yīng)式編程基礎(chǔ),Reactor 提供了非阻塞的編程模型和工具,包括 Flux 和 Mono 等反應(yīng)式類型。

  11. WebClient:這是 Spring 5 中引入的非阻塞、支持響應(yīng)式流的 HTTP 客戶端,用于與其它服務(wù)進(jìn)行通信。

  12. Spring Data Reactive:提供對響應(yīng)式數(shù)據(jù)訪問的支持,例如 Reactive Repositories。

  13. Spring Security Reactive:提供對響應(yīng)式安全訪問控制的支持。

  14. HttpHandler:定義了最低級別的反應(yīng)式 HTTP 請求處理合同,作為不同運行時之間的共同基礎(chǔ)。

  15. ContextPathCompositeHandler:允許在不同的上下文路徑上注冊多個應(yīng)用程序。

這些組件共同工作,為開發(fā)人員提供了一個強(qiáng)大且靈活的響應(yīng)式 Web 應(yīng)用開發(fā)平臺。通過這些組件,開發(fā)者可以構(gòu)建出能夠高效處理大量并發(fā)請求的應(yīng)用程序。下面針對這些組件,V 哥將一一詳細(xì)介紹核心源碼的實現(xiàn)過程,幫助兄弟們徹底理解。

1. DispatcherHandler

DispatcherHandler 是 Spring WebFlux 的核心組件,它的作用類似于 Spring MVC 中的 DispatcherServlet。它負(fù)責(zé)將傳入的 HTTP 請求分發(fā)給相應(yīng)的處理器(handler),并處理請求的映射、調(diào)用和結(jié)果處理。以下是對 DispatcherHandler 組件源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

初始化過程

  • ApplicationContextAware 實現(xiàn):DispatcherHandler 實現(xiàn)了 ApplicationContextAware 接口,這意味著它可以訪問到 Spring 應(yīng)用上下文中的 Bean。

  • HandlerMapping、HandlerAdapter 和 HandlerResultHandler 的初始化:DispatcherHandler 在初始化時會查找 Spring 應(yīng)用上下文中所有的 HandlerMapping、HandlerAdapter 和 HandlerResultHandler 并初始化它們。

    protected void initStrategies(ApplicationContext context) {
        // ... 省略部分代碼 ...
        this.handlerMappings = ...;
        this.handlerAdapters = ...;
        this.resultHandlers = ...;
    }

請求處理過程

  • 獲取 HandlerMappings:DispatcherHandler 會通過 handlerMappings 來查找能夠處理當(dāng)前請求的 HandlerMapping。

  • 映射請求到 Handler:使用找到的 HandlerMapping 將請求映射到具體的處理器(可能是一個 @Controller 方法或者一個 RouterFunction)。

  • 調(diào)用 Handler:一旦找到處理器,DispatcherHandler 會使用適當(dāng)?shù)?HandlerAdapter 來調(diào)用處理器。

  • 處理結(jié)果:處理器的執(zhí)行結(jié)果會被 HandlerResultHandler 處理,生成響應(yīng)。

核心方法:handle

DispatcherHandler 的核心方法是 handle,它定義了請求處理的流程:

public Mono handle(ServerWebExchange exchange) {
    // 檢查是否初始化了 handlerMappings
    if (this.handlerMappings == null) {
        return createNotFoundError();
    }
    // 使用 handlerMappings 來查找 handler
    return Flux.fromIterable(this.handlerMappings)
            .concatMap(mapping -> mapping.getHandler(exchange))
            .next() // 獲取第一個 handler
            .switchIfEmpty(createNotFoundError()) // 如果沒有找到 handler,返回錯誤
            .flatMap(handler -> invokeHandler(exchange, handler)) // 調(diào)用 handler
            .flatMap(result -> handleResult(exchange, result)); // 處理結(jié)果
}

錯誤處理

  • createNotFoundError:如果沒有找到合適的處理器,DispatcherHandler 會創(chuàng)建一個表示 "Not Found" 的響應(yīng)。

其他組件的協(xié)同工作

  • HandlerMapping:負(fù)責(zé)將請求 URL 映射到具體的處理器。
  • HandlerAdapter:負(fù)責(zé)調(diào)用具體的處理器,Spring WebFlux 支持多種類型的處理器,HandlerAdapter 使得 DispatcherHandler 無需關(guān)心具體的調(diào)用細(xì)節(jié)。
  • HandlerResultHandler:負(fù)責(zé)處理處理器的返回值,并將其轉(zhuǎn)換為 HTTP 響應(yīng)。

DispatcherHandler 的設(shè)計使得它非常靈活,可以很容易地擴(kuò)展新的 HandlerMapping、HandlerAdapter 或 HandlerResultHandler 來支持不同的處理器類型和返回類型。

以上就是 DispatcherHandler 組件的源碼實現(xiàn)邏輯和步驟的分析。通過這種方式,Spring WebFlux 能夠以非阻塞的方式處理 Web 請求,提高應(yīng)用的性能和可伸縮性。

2. HandlerMapping

HandlerMapping 是 Spring WebFlux 中的一個接口,它定義了將請求映射到處理器(handler)的邏輯。HandlerMapping 的實現(xiàn)類負(fù)責(zé)根據(jù)請求的類型、URL 模式等信息來確定哪個具體的處理器應(yīng)該處理當(dāng)前的請求。以下是對 HandlerMapping 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

HandlerMapping 接口定義

HandlerMapping 接口定義了以下關(guān)鍵方法:

public interface HandlerMapping {
    Mono getHandler(ServerWebExchange exchange);
    void afterPropertiesSet();
}

 
  • getHandler:根據(jù)給定的 ServerWebExchange 對象,返回一個 Mono 對象,該 Mono 完成時包含請求的處理器。
  • afterPropertiesSet:在所有屬性都設(shè)置之后調(diào)用,允許 HandlerMapping 實現(xiàn)進(jìn)行初始化。

主要實現(xiàn)類

Spring WebFlux 提供了幾個 HandlerMapping 的實現(xiàn)類,主要包括:

  • RequestMappingHandlerMapping:處理基于注解的映射,例如 @RequestMapping、@GetMapping 等。

  • RouterFunctionMapping:處理基于 RouterFunction 的函數(shù)式路由。

  • SimpleUrlHandlerMapping:處理簡單的 URL 到對象的映射。

RequestMappingHandlerMapping 源碼分析

RequestMappingHandlerMapping 是最常用的 HandlerMapping 實現(xiàn)之一,下面是它的一些關(guān)鍵實現(xiàn)邏輯:

  • 注冊和解析:在初始化時,RequestMappingHandlerMapping 會掃描所有的 beans,查找?guī)в?@RequestMapping 注解的方法,并注冊這些方法作為請求的處理器。

  • 映射處理:RequestMappingHandlerMapping 使用 Pattern 對象來存儲和匹配 URL 模式。

  • getHandler 方法實現(xiàn):

@Override
public Mono getHandler(ServerWebExchange exchange) {
    String lookupPath = getPath(exchange);
    return getHandlerInternal(exchange)
            .filter(h -> matchesRoute(lookupPath, h))
            .switchIfEmpty(Mono.defer(() -> getBestMatchingHandler(lookupPath, exchange)));
}

 
  • getPath:從 ServerWebExchange 中提取請求路徑。
  • getHandlerInternal:返回一個包含所有注冊處理器的 Mono。
  • filter 和 matchesRoute:檢查處理器是否與請求路徑匹配。
  • getBestMatchingHandler:如果沒有找到精確匹配的處理器,嘗試找到最佳匹配的處理器。

映射匹配邏輯

映射匹配邏輯通常涉及以下步驟:

  • 路徑匹配:檢查請求的路徑是否與注冊的 URL 模式匹配。

  • 請求方法匹配:如果 URL 模式匹配,進(jìn)一步檢查請求的方法(GET、POST 等)是否與處理器支持的方法匹配。

  • 參數(shù)條件匹配:檢查請求是否包含處理器所需的參數(shù)。

  • 頭信息匹配:檢查請求頭是否滿足特定的條件。

  • 消費和產(chǎn)生媒體類型匹配:檢查請求的 Accept 頭和 Content-Type 是否與處理器支持的媒體類型匹配。

性能優(yōu)化

RequestMappingHandlerMapping 還實現(xiàn)了一些性能優(yōu)化措施,例如緩存匹配的 URL 模式,以減少重復(fù)的模式匹配操作。

小結(jié)一下

HandlerMapping 組件是 Spring WebFlux 請求處理流程中的關(guān)鍵部分,它負(fù)責(zé)將進(jìn)入的請求映射到正確的處理器。通過使用不同的 HandlerMapping 實現(xiàn),Spring WebFlux 支持靈活的請求映射策略,以適應(yīng)不同的應(yīng)用場景。

3. HandlerAdapter

HandlerAdapter 接口在 Spring WebFlux 中扮演著至關(guān)重要的角色,它的作用是將 DispatcherHandler 找到的處理器(handler)適配到具體的執(zhí)行邏輯上。HandlerAdapter 使得 DispatcherHandler 無需關(guān)心具體的處理器類型,只需要通過 HandlerAdapter 來調(diào)用處理器即可。以下是對 HandlerAdapter 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:
HandlerAdapter 接口定義

HandlerAdapter 接口定義了以下關(guān)鍵方法:

public interface HandlerAdapter {
    boolean supports(Object handler);
    Mono handle(ServerWebExchange exchange, Object handler, Object... args);
}
  • supports:檢查給定的處理器是否被當(dāng)前 HandlerAdapter 支持。
  • handle:調(diào)用處理器,并返回一個 Mono 對象,表示異步的調(diào)用過程。

主要實現(xiàn)類

Spring WebFlux 提供了幾個 HandlerAdapter 的實現(xiàn)類,主要包括:

  • RequestMappingHandlerAdapter:支持基于注解的控制器方法,如帶有 @RequestMapping 注解的方法。

  • HttpHandlerAdapter:支持 HttpHandler 接口的處理器。

  • ControllerEndpointHandlerAdapter:支持 ControllerEndpoint 接口的處理器,通常用于 WebFlux 函數(shù)式編程。

  • RouterFunctionHandlerAdapter:支持 RouterFunction 接口,用于函數(shù)式路由。

RequestMappingHandlerAdapter 源碼分析

RequestMappingHandlerAdapter 是最常用的 HandlerAdapter 實現(xiàn)之一,下面是它的一些關(guān)鍵實現(xiàn)邏輯:

  • 支持性檢查:supports 方法檢查給定的處理器是否是 Controller 或者 RequestMapping 注解的方法。
@Override
public boolean supports(Object handler) {
    return (handler instanceof HandlerFunction) ||
           (handler instanceof Controller) ||
           AnnotationUtils.findAnnotation(handler.getClass(), RequestMapping.class) != null;
}

調(diào)用處理器:handle 方法調(diào)用處理器,并處理返回值。

    @Override
    public Mono handle(ServerWebExchange exchange, Object handler) {
        // 調(diào)用具體的處理器
        return ((HandlerFunction) handler).handle(exchange);
    }

調(diào)用處理器的邏輯

調(diào)用處理器的邏輯通常涉及以下步驟:

  • 參數(shù)解析:解析請求中的參數(shù),并將其轉(zhuǎn)換為方法參數(shù)。

  • 調(diào)用方法:調(diào)用處理器的方法,并將解析后的參數(shù)傳遞給方法。

  • 處理返回值:處理方法的返回值,將其轉(zhuǎn)換為響應(yīng)。

  • 異步處理:如果處理器返回的是 Mono 或 Flux,HandlerAdapter 需要處理這些異步結(jié)果。

錯誤處理

HandlerAdapter 還負(fù)責(zé)處理調(diào)用過程中的異常,將異常轉(zhuǎn)換為合適的響應(yīng)。

小結(jié)一下

HandlerAdapter 組件是 Spring WebFlux 請求處理流程中的關(guān)鍵部分,它解耦了 DispatcherHandler 和具體的處理器實現(xiàn)。通過使用不同的 HandlerAdapter 實現(xiàn),Spring WebFlux 支持了多種類型的處理器,包括基于注解的控制器、函數(shù)式路由以及 HttpHandler 接口的實現(xiàn)。這種設(shè)計提高了框架的靈活性和可擴(kuò)展性。

4. HandlerResultHandler

HandlerResultHandler 組件在 Spring WebFlux 中負(fù)責(zé)處理由 HandlerAdapter 調(diào)用處理器后返回的結(jié)果。它將這些結(jié)果轉(zhuǎn)換為客戶端可以接收的 HTTP 響應(yīng)。以下是對 HandlerResultHandler 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

HandlerResultHandler 接口定義

HandlerResultHandler 接口定義了以下關(guān)鍵方法:

public interface HandlerResultHandler {
    boolean supports(HandlerResult result);
    Mono handleResult(ServerWebExchange exchange, HandlerResult result);
}
  • supports:檢查給定的 HandlerResult 是否被當(dāng)前 HandlerResultHandler 支持。
  • handleResult:處理 HandlerResult,生成響應(yīng)并返回一個 Mono 對象,表示異步的處理過程。

主要實現(xiàn)類

Spring WebFlux 提供了幾個 HandlerResultHandler 的實現(xiàn)類,主要包括:

  • ServerResponseResultHandler:處理 ServerResponse 類型的返回值。
  • ResponseEntityResultHandler:處理 ResponseEntity 類型的返回值。
  • ModelAndViewResultHandler:處理 ModelAndView 類型的返回值,通常用于視圖渲染。

ServerResponseResultHandler 源碼分析

ServerResponseResultHandler 是處理 ServerResponse 類型結(jié)果的 HandlerResultHandler 實現(xiàn):

  • 支持性檢查:supports 方法檢查 HandlerResult 是否包含 ServerResponse 對象。
@Override
public boolean supports(HandlerResult result) {
    return result.getReturnValue() instanceof ServerResponse;
}
  • 處理結(jié)果:handleResult 方法處理 ServerResponse 對象,并生成響應(yīng)。
    @Override
    public Mono handleResult(ServerWebExchange exchange, HandlerResult result) {
        ServerResponse response = (ServerResponse) result.getReturnValue();
        return response.writeTo(exchange, result.isCommitted());
    }

處理結(jié)果的邏輯

處理結(jié)果的邏輯通常涉及以下步驟:

  • 獲取返回值:從 HandlerResult 中獲取處理器的返回值。

  • 檢查類型:根據(jù)返回值的類型,選擇合適的處理邏輯。

  • 生成響應(yīng):將返回值轉(zhuǎn)換為 HTTP 響應(yīng)。例如,ServerResponse 已經(jīng)包含了響應(yīng)的狀態(tài)碼、頭信息和體。

  • 異步處理:如果返回值是異步的(如 Mono 或 Flux),則需要處理這些異步結(jié)果。

  • 寫入響應(yīng):將生成的響應(yīng)寫入到 ServerWebExchange 中。

錯誤處理

HandlerResultHandler 還負(fù)責(zé)處理結(jié)果處理過程中的異常,將異常轉(zhuǎn)換為合適的響應(yīng)。

小結(jié)一下

HandlerResultHandler 組件是 Spring WebFlux 請求處理流程中的關(guān)鍵部分,它負(fù)責(zé)將處理器的返回值轉(zhuǎn)換為 HTTP 響應(yīng)。通過使用不同的 HandlerResultHandler 實現(xiàn),Spring WebFlux 支持了多種返回值類型,包括 ServerResponse、ResponseEntity 和 ModelAndView。這種設(shè)計提高了框架的靈活性和可擴(kuò)展性,允許開發(fā)者以不同的方式處理響應(yīng)結(jié)果。

HandlerResultHandler 的實現(xiàn)通常需要考慮響應(yīng)的異步特性,確保即使在異步流的情況下也能正確地生成和發(fā)送響應(yīng)。此外,它還需要與 ServerWebExchange 緊密協(xié)作,以便訪問和操作請求和響應(yīng)的上下文信息。

5. WebFilter

WebFilter 接口是 Spring WebFlux 中用于攔截和處理 Web 請求和響應(yīng)的組件。它允許開發(fā)者在請求到達(dá)具體的處理器之前或之后,對請求或響應(yīng)進(jìn)行額外的處理,例如日志記錄、安全性檢查、跨域處理等。以下是對 WebFilter 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

WebFilter 接口定義

WebFilter 接口定義了以下關(guān)鍵方法:

public interface WebFilter {
    Mono filter(ServerWebExchange exchange, WebFilterChain chain);
}
  • filter:對給定的 ServerWebExchange 對象進(jìn)行處理,并通過 WebFilterChain 調(diào)用鏈中的下一個 WebFilter 或最終的處理器。

過濾器鏈

在 Spring WebFlux 中,WebFilter 通常會被組織成一個過濾器鏈,每個 WebFilter 都可以決定是繼續(xù)過濾請求還是將請求傳遞給鏈中的下一個 WebFilter。這種鏈?zhǔn)秸{(diào)用模式使得過濾器的執(zhí)行順序非常重要。

主要實現(xiàn)類

Spring WebFlux 提供了一些內(nèi)置的 WebFilter 實現(xiàn)類,例如:

  • ServerHttpSecurity:用于安全性檢查。
  • CorsFilter:用于處理跨源資源共享(CORS)。
  • WebFilterChain:代表過濾器鏈的上下文,允許調(diào)用鏈中的下一個 WebFilter。

過濾器鏈的構(gòu)建

過濾器鏈通常在應(yīng)用程序的配置中構(gòu)建,例如使用 WebFilter 接口的實現(xiàn)類:

@Configuration
public class WebFluxConfig {
    @Bean
    public WebFilter myCustomFilter() {
        return (exchange, chain) -> {
            // 在這里可以對請求進(jìn)行預(yù)處理
            return chain.filter(exchange).subscriberContext(ctx -> ctx.put("customKey", "customValue"));
        };
    }
}

WebFilter 的實現(xiàn)邏輯

實現(xiàn) WebFilter 接口的 filter 方法通常涉及以下步驟:

  • 預(yù)處理:在調(diào)用 chain.filter(exchange) 之前,對 ServerWebExchange 進(jìn)行任何必要的預(yù)處理,例如修改請求頭、查詢參數(shù)等。

  • 調(diào)用鏈:使用 WebFilterChain 的 filter 方法將請求傳遞給鏈中的下一個 WebFilter。這通常會返回一個 Mono ,表示異步的過濾過程。

  • 后處理:在 chain.filter(exchange) 完成后,對 ServerWebExchange 進(jìn)行任何必要的后處理,例如修改響應(yīng)頭、響應(yīng)體等。

  • 錯誤處理:處理在過濾過程中可能發(fā)生的異常,并決定是拋出新的錯誤、返回特定的響應(yīng)或繼續(xù)過濾鏈。

異步處理

由于 filter 方法返回的是 Mono ,WebFilter 的實現(xiàn)需要考慮異步處理。這意味著在過濾過程中,可以返回異步的響應(yīng),而不會阻塞整個請求的處理。

小結(jié)一下

WebFilter 組件是 Spring WebFlux 中用于攔截和處理 Web 請求和響應(yīng)的強(qiáng)大工具。通過實現(xiàn) WebFilter 接口并構(gòu)建過濾器鏈,開發(fā)者可以靈活地對請求和響應(yīng)進(jìn)行預(yù)處理和后處理,以及實現(xiàn)各種橫切關(guān)注點,如安全性、日志記錄、CORS 處理等。這種設(shè)計提高了應(yīng)用程序的模塊性和可維護(hù)性,同時保持了非阻塞和異步的特性。

6. ServerWebExchange

ServerWebExchange 是 Spring WebFlux 中的一個核心組件,它封裝了 HTTP 請求和響應(yīng)的上下文信息,為 Web 服務(wù)器和應(yīng)用程序之間提供了一個交互的接口。以下是對 ServerWebExchange 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

ServerWebExchange 接口定義

ServerWebExchange 接口定義了對 HTTP 請求和響應(yīng)的訪問和操作:

public interface ServerWebExchange {
    ServerHttpRequest getRequest();
    ServerHttpResponse getResponse();
    void beforeCommit();
    boolean isCommitted();
    void setCommitted(boolean committed);
    Context getContext();
}
  • getRequest():返回當(dāng)前的 ServerHttpRequest 對象,包含請求的詳細(xì)信息。
  • getResponse():返回當(dāng)前的 ServerHttpResponse 對象,用于構(gòu)造響應(yīng)。
  • beforeCommit():在響應(yīng)提交之前調(diào)用,允許進(jìn)行一些清理或準(zhǔn)備操作。
  • isCommitted():檢查響應(yīng)是否已經(jīng)提交。
  • setCommitted(boolean committed):設(shè)置響應(yīng)是否提交的狀態(tài)。
  • getContext():返回與當(dāng)前交換關(guān)聯(lián)的 Context,用于存儲和傳遞附加信息。

核心屬性

ServerWebExchange 通常包含以下核心屬性:

  • request:ServerHttpRequest 對象,封裝了 HTTP 請求的詳細(xì)信息,如頭信息、URI、方法等。
  • response:ServerHttpResponse 對象,用于構(gòu)造和發(fā)送 HTTP 響應(yīng)。
  • principal:可能包含當(dāng)前請求的認(rèn)證主體(Principal)。
  • session:可能包含當(dāng)前請求的會話信息。
  • attributes:一個 Map,用于存儲與請求相關(guān)的屬性。

請求和響應(yīng)的處理

ServerWebExchange 在請求和響應(yīng)的處理中扮演著核心角色:

  • 請求獲。和ㄟ^ getRequest() 方法獲取請求對象,訪問請求的各種信息。

  • 響應(yīng)構(gòu)造:通過 getResponse() 方法獲取響應(yīng)對象,構(gòu)造響應(yīng)的狀態(tài)碼、頭信息和響應(yīng)體。

  • 上下文管理:使用 Context 對象存儲和傳遞請求和響應(yīng)過程中的附加信息。

  • 提交管理:通過 beforeCommit()、isCommitted() 和 setCommitted() 方法管理響應(yīng)的提交狀態(tài)。

  • 過濾器鏈:在 WebFilter 的實現(xiàn)中,ServerWebExchange 對象在過濾器鏈中傳遞,每個過濾器都可以訪問和修改請求和響應(yīng)。

異步處理

由于 WebFlux 是響應(yīng)式的,ServerWebExchange 支持異步處理:

  • 響應(yīng)可以通過非阻塞的方式寫入,例如使用 ServerHttpResponse 的異步方法。
  • 請求和響應(yīng)的處理可以在不同的線程或事件循環(huán)中進(jìn)行。

小結(jié)一下

ServerWebExchange 是 Spring WebFlux 中處理 HTTP 請求和響應(yīng)的核心組件。它提供了一個統(tǒng)一的接口來訪問和操作請求和響應(yīng)數(shù)據(jù),同時支持異步非阻塞的處理方式。通過 ServerWebExchange,開發(fā)者可以在 Web 服務(wù)器和應(yīng)用程序之間進(jìn)行高效的數(shù)據(jù)交換和狀態(tài)管理,實現(xiàn)高性能的響應(yīng)式 Web 應(yīng)用。

ServerWebExchange 的實現(xiàn)通常需要考慮響應(yīng)式的編程模型,確保在處理請求和構(gòu)造響應(yīng)時不會阻塞事件循環(huán),從而充分利用 WebFlux 的性能優(yōu)勢。此外,它還提供了豐富的上下文管理功能,使得在復(fù)雜的請求處理流程中,可以方便地存儲和傳遞附加信息。

7. ServerHttpRequest和ServerHttpResponse

ServerHttpRequest 和 ServerHttpResponse 是 Spring WebFlux 中的兩個核心接口,它們分別表示服務(wù)器接收的 HTTP 請求和發(fā)送的 HTTP 響應(yīng)。以下是對這兩個組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

ServerHttpRequest 接口定義

ServerHttpRequest 接口定義了對 HTTP 請求的訪問:

public interface ServerHttpRequest {
    URI getURI();
    HttpMethod getMethod();
    String getHeader(String headerName);
    MultiValueMap getHeaders();
    DataBufferFactory bufferFactory();
    // 省略其他方法...
}
  • getURI():返回請求的 URI。
  • getMethod():返回 HTTP 方法(如 GET、POST 等)。
  • getHeader(String headerName):根據(jù)名稱獲取請求頭的值。
  • getHeaders():返回包含所有請求頭的 MultiValueMap。
  • bufferFactory():返回用于創(chuàng)建數(shù)據(jù)緩沖區(qū)(DataBuffer)的工廠。

ServerHttpResponse 接口定義

ServerHttpResponse 接口定義了對 HTTP 響應(yīng)的構(gòu)造和發(fā)送:

public interface ServerHttpResponse {
    HttpStatusSeriesStatus.Series getStatusSeries();
    void setStatusCode(HttpStatus statusCode);
    String getHeader(String headerName);
    MultiValueMap getHeaders();
    void setComplete();
    DataBufferFactory bufferFactory();
    Mono writeWith(Publisher body);
    // 省略其他方法...
}
  • getStatusSeries():返回響應(yīng)的狀態(tài)碼系列(如 2xx、3xx 等)。
  • setStatusCode(HttpStatus statusCode):設(shè)置 HTTP 狀態(tài)碼。
  • getHeader(String headerName):根據(jù)名稱獲取響應(yīng)頭的值。
  • getHeaders():返回包含所有響應(yīng)頭的 MultiValueMap。
  • setComplete():標(biāo)記響應(yīng)為完成。
  • writeWith(Publisher body) :發(fā)送響應(yīng)體。

請求和響應(yīng)的處理

ServerHttpRequest 和 ServerHttpResponse 在處理 HTTP 請求和響應(yīng)中扮演著核心角色:

  • 請求信息獲。和ㄟ^ ServerHttpRequest 的方法獲取請求的 URI、方法、頭信息等。

  • 響應(yīng)構(gòu)造:使用 ServerHttpResponse 的方法設(shè)置狀態(tài)碼、頭信息,并構(gòu)造響應(yīng)體。

  • 數(shù)據(jù)緩沖區(qū):通過 bufferFactory() 方法獲取 DataBufferFactory,用于創(chuàng)建和管理數(shù)據(jù)緩沖區(qū)。

  • 異步發(fā)送:ServerHttpResponse 的 writeWith(Publisher body) 方法支持異步發(fā)送響應(yīng)體。

  • 流式處理:支持以流式的方式讀取請求體和寫入響應(yīng)體。

異步非阻塞

由于 WebFlux 是基于響應(yīng)式編程模型的,ServerHttpRequest 和 ServerHttpResponse 支持異步非阻塞的操作:

  • 請求體和響應(yīng)體可以通過 Publisher 形式異步讀取和發(fā)送。
  • 響應(yīng)的發(fā)送不會阻塞事件循環(huán)。

小結(jié)一下

ServerHttpRequest 和 ServerHttpResponse 是 Spring WebFlux 中處理 HTTP 請求和響應(yīng)的接口。它們提供了豐富的方法來訪問請求信息、構(gòu)造響應(yīng),并支持異步非阻塞的操作。通過這兩個接口,開發(fā)者可以構(gòu)建高性能、響應(yīng)式的 Web 應(yīng)用,充分利用現(xiàn)代硬件和軟件架構(gòu)的優(yōu)勢。

在實際應(yīng)用中,開發(fā)者通常不需要直接實現(xiàn)這些接口,而是通過框架提供的實現(xiàn)類來操作請求和響應(yīng)。這些實現(xiàn)類通常會與特定的運行時環(huán)境(如 Netty)集成,以提供高效的 I/O 操作。

8. WebSession

WebSession 組件在 Spring WebFlux 中用于表示和管理 Web 會話(session)。它提供了一種機(jī)制來存儲和檢索與特定用戶會話相關(guān)的數(shù)據(jù)。以下是對 WebSession 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

WebSession 接口定義

WebSession 接口定義了 Web 會話的基本操作:

public interface WebSession {
    String getId();
    Mono save();
    void invalidate();
    Map getAttributes();
     T getAttribute(String name);
     void setAttribute(String name, T value);
    default  Mono getAttributeOrDefault(String name, Supplier defaultValue);
    // 省略其他方法...
}
  • getId():獲取會話的唯一標(biāo)識符。
  • save():保存會話的更改。
  • invalidate():使會話無效,相當(dāng)于會話過期。
  • getAttributes():獲取會話的所有屬性。
  • getAttribute(String name):根據(jù)名稱獲取會話屬性。
  • setAttribute(String name, T value):設(shè)置會話屬性。

WebSession 的實現(xiàn)邏輯

  • 會話創(chuàng)建:WebSession 可以在請求處理過程中創(chuàng)建,通常與 ServerWebExchange 關(guān)聯(lián)。

  • 屬性管理:會話屬性存儲在 getAttributes() 返回的 Map 中,允許存儲和檢索用戶特定的信息。

  • 異步保存:save() 方法異步保存會話更改,這可能涉及將更改寫入底層存儲。

  • 會話失效:invalidate() 方法用于使會話無效,確保會話數(shù)據(jù)不再可用。

  • 會話 ID 管理:每個 WebSession 實例都有一個唯一的 id,用于標(biāo)識特定的用戶會話。

  • 默認(rèn)值獲。篻etAttributeOrDefault() 方法提供了一種便捷的方式來獲取屬性值,如果屬性不存在,則返回默認(rèn)值。

會話的存儲和檢索

WebSession 的實現(xiàn)通常需要考慮以下方面:

  • 存儲機(jī)制:會話數(shù)據(jù)可以存儲在不同的介質(zhì)中,例如內(nèi)存、數(shù)據(jù)庫或分布式緩存。
  • 并發(fā)處理:在多線程或異步環(huán)境中,需要確保會話數(shù)據(jù)的一致性。
  • 會話超時:實現(xiàn)會話超時邏輯,自動使過期的會話無效。

會話的創(chuàng)建和綁定

在請求處理過程中,WebSession 可以被創(chuàng)建和綁定到 ServerWebExchange:

ServerWebExchange exchange = ...;
Mono sessionMono = exchange.getSession();
sessionMono.flatMap(session -> {
    // 使用會話
    return session.save();
});

小結(jié)一下

WebSession 組件是 Spring WebFlux 中用于管理 Web 會話的接口。它提供了一種靈活的方式來存儲和檢索與用戶會話相關(guān)的數(shù)據(jù),同時支持異步操作和多種存儲選項。通過 WebSession,開發(fā)者可以輕松實現(xiàn)用戶會話跟蹤和管理,構(gòu)建具有個性化用戶體驗的 Web 應(yīng)用。

在實際應(yīng)用中,開發(fā)者可以根據(jù)需要選擇不同的會話存儲實現(xiàn),例如使用 Spring Session 項目提供的多種存儲解決方案,包括 Redis、Hazelcast、JDBC 等。這些實現(xiàn)通常會處理會話的創(chuàng)建、保存、失效等邏輯,并與 WebSession 接口進(jìn)行集成。

9. Reactive Streams

Reactive Streams 是一個規(guī)范,它定義了異步流處理的接口和行為,以便在不同的庫和框架之間實現(xiàn)互操作性。Spring WebFlux 作為響應(yīng)式編程的一部分,遵循 Reactive Streams 規(guī)范。以下是對 Reactive Streams 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

Reactive Streams 核心接口

Reactive Streams 規(guī)范定義了以下幾個核心接口:

  1. Publisher :發(fā)布者,表示可以產(chǎn)生數(shù)據(jù)的源頭。
  2. Subscriber :訂閱者,表示接收并處理數(shù)據(jù)的消費者。
  3. Subscription :訂閱關(guān)系,用于管理數(shù)據(jù)的請求和發(fā)送。
  4. Processor :處理器,是 Publisher 和 Subscriber 的結(jié)合體。

Publisher 接口

Publisher 接口是 Reactive Streams 的核心,它定義了如何將數(shù)據(jù)推送給 Subscriber:

public interface Publisher {
void subscribe( Subscriber s);
}

subscribe(`Subscriber s`):允許 Subscriber 訂閱 Publisher。

Subscriber 接口

Subscriber 接口定義了如何處理從 Publisher 接收到的數(shù)據(jù):

public interface Subscriber {
    void onSubscribe(Subscription s);
    void onNext(T t);
    void onError(Throwable t);
    void onComplete();
}
  • onSubscribe(Subscription s):當(dāng) Subscriber 訂閱 Publisher 后被調(diào)用,Subscription 用于控制數(shù)據(jù)流。
  • onNext(T t):接收到新數(shù)據(jù)時調(diào)用。
  • onError(Throwable t):發(fā)生錯誤時調(diào)用。
  • onComplete():數(shù)據(jù)流結(jié)束時調(diào)用。

Subscription 接口

Subscription 接口用于管理 Subscriber 和 Publisher 之間的數(shù)據(jù)流:

public interface Subscription {
    void request(long n);
    void cancel();
}
  • request(long n):請求 Publisher 發(fā)送指定數(shù)量的數(shù)據(jù)項。
  • cancel():取消訂閱,停止接收數(shù)據(jù)。

Processor 接口

Processor 是 Publisher 和 Subscriber 的結(jié)合體,可以接收數(shù)據(jù)并產(chǎn)生新的數(shù)據(jù)流:

public interface Processor extends Subscriber, Publisher {
    // 繼承自 Subscriber 和 Publisher 的方法
}

源碼實現(xiàn)邏輯

  • 數(shù)據(jù)流創(chuàng)建:使用 Publisher 創(chuàng)建數(shù)據(jù)流。
  • 訂閱機(jī)制:Subscriber 通過調(diào)用 Publisher 的 subscribe 方法訂閱數(shù)據(jù)流。
  • 數(shù)據(jù)請求:Subscriber 使用 Subscription 的 request 方法控制數(shù)據(jù)的接收速率。
  • 數(shù)據(jù)推送:Publisher 根據(jù) Subscriber 的請求發(fā)送數(shù)據(jù)項給 Subscriber。
  • 錯誤和完成處理:Publisher 在發(fā)生錯誤或數(shù)據(jù)流結(jié)束時,分別調(diào)用 Subscriber 的 onError 或 onComplete 方法。
  • 取消訂閱:Subscriber 可以通過調(diào)用 Subscription 的 cancel 方法取消訂閱。

步驟

  • 初始化:創(chuàng)建 Publisher 和 Subscriber 對象。
  • 訂閱:Subscriber 調(diào)用 Publisher 的 subscribe 方法。
  • 處理訂閱:Publisher 調(diào)用 Subscriber 的 onSubscribe 方法,傳入 Subscription 對象。
  • 請求數(shù)據(jù):Subscriber 使用 Subscription 請求數(shù)據(jù)。
  • 發(fā)送數(shù)據(jù):Publisher 根據(jù)請求發(fā)送數(shù)據(jù)給 Subscriber。
  • 完成或錯誤:Publisher 在數(shù)據(jù)發(fā)送完畢后調(diào)用 onComplete,或在發(fā)生錯誤時調(diào)用 onError。

小結(jié)一下

Reactive Streams 規(guī)范提供了一種異步、非阻塞的數(shù)據(jù)處理模型,Spring WebFlux 通過實現(xiàn)這些接口,支持響應(yīng)式編程。這種模型允許系統(tǒng)更有效地處理并發(fā)數(shù)據(jù)流,提高性能和可伸縮性。開發(fā)者可以利用 Reactive Streams 規(guī)范提供的接口和機(jī)制,構(gòu)建高效、彈性的響應(yīng)式應(yīng)用程序。

10. Reactor 庫

Reactor 是一個基于 Reactive Streams 規(guī)范的庫,用于構(gòu)建異步、非阻塞的響應(yīng)式應(yīng)用程序。它是 Spring WebFlux 的反應(yīng)式編程基礎(chǔ)。以下是對 Reactor 庫組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

Reactor 核心組件

Reactor 提供了以下核心組件:

  • Flux:代表一個包含 0 到 N 個元素的響應(yīng)式序列。
  • Mono:代表一個包含 0 到 1 個元素的響應(yīng)式序列。
  • Scheduler:用于控制并發(fā)和執(zhí)行異步操作的調(diào)度器。

Flux 和 Mono 的實現(xiàn)邏輯

  • 數(shù)據(jù)流創(chuàng)建:通過靜態(tài)方法(如 Flux.just(), Mono.just())或構(gòu)造函數(shù)創(chuàng)建 Flux 或 Mono 實例。

  • 操作符:Reactor 提供了豐富的操作符來處理數(shù)據(jù)流,例如 map、flatMap、filter 等。

  • 訂閱機(jī)制:通過 subscribe() 方法訂閱數(shù)據(jù)流,并提供 Subscriber 來接收數(shù)據(jù)。

  • 數(shù)據(jù)請求:使用 request() 方法控制數(shù)據(jù)的請求數(shù)量。

  • 數(shù)據(jù)推送:數(shù)據(jù)通過 onNext() 方法推送給訂閱者。

  • 錯誤和完成處理:通過 onError() 和 onComplete() 方法處理數(shù)據(jù)流的錯誤和完成事件。

Scheduler 的實現(xiàn)邏輯

  • 調(diào)度器創(chuàng)建:創(chuàng)建 Scheduler 實例,例如使用 Schedulers.parallel() 創(chuàng)建并行調(diào)度器。

  • 任務(wù)調(diào)度:使用 schedule() 方法調(diào)度任務(wù),返回 Mono 或 Flux。

  • 并發(fā)控制:Scheduler 可以控制任務(wù)的并發(fā)執(zhí)行,例如限制并發(fā)數(shù)量。

  • 異步執(zhí)行:任務(wù)在非阻塞的線程池中異步執(zhí)行。

源碼實現(xiàn)步驟

  • 定義數(shù)據(jù)源:創(chuàng)建 Flux 或 Mono 實例作為數(shù)據(jù)源。

  • 應(yīng)用操作符:使用操作符對數(shù)據(jù)流進(jìn)行轉(zhuǎn)換、過濾或組合。

  • 錯誤處理:使用 onErrorResume() 或 doOnError() 等操作符處理錯誤。

  • 背壓管理:使用 onBackpressureBuffer() 或 onBackpressureDrop() 等操作符處理背壓。

  • 訂閱和消費:調(diào)用 subscribe() 方法訂閱數(shù)據(jù)流,并提供 Subscriber 來消費數(shù)據(jù)。

  • 調(diào)度任務(wù):使用 Scheduler 調(diào)度異步任務(wù)。

  • 資源清理:使用 dispose() 方法在不再需要時釋放資源。

小結(jié)一下

Reactor 庫通過 Flux、Mono 和 Scheduler 等組件,提供了一種強(qiáng)大的方式來構(gòu)建響應(yīng)式應(yīng)用程序。它遵循 Reactive Streams 規(guī)范,支持異步非阻塞的數(shù)據(jù)流處理。Reactor 的操作符豐富,可以輕松實現(xiàn)復(fù)雜的數(shù)據(jù)處理邏輯。同時,它還提供了靈活的并發(fā)控制和調(diào)度機(jī)制,以適應(yīng)不同的應(yīng)用場景。

Reactor 的設(shè)計哲學(xué)是提供聲明式的數(shù)據(jù)處理能力,讓開發(fā)者能夠以一種直觀和靈活的方式構(gòu)建響應(yīng)式系統(tǒng)。通過 Reactor,開發(fā)者可以充分利用現(xiàn)代硬件的多核特性,提高應(yīng)用程序的性能和可伸縮性。

11. WebClient

WebClient 是 Spring WebFlux 中用于發(fā)起 HTTP 請求的非阻塞響應(yīng)式客戶端。它允許你以聲明式的方式構(gòu)建請求并處理響應(yīng)。以下是對 WebClient 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

WebClient 接口定義

WebClient 提供了發(fā)起請求的方法:

public interface WebClient {
    default URI uri() {
        return URI.create(this.baseUrl);
    }

     Mono getForObject(String url, Class responseType, Object... uriVariables);
     Flux getForFlux(String url, Class elementType, Object... uriVariables);
    // 其他 HTTP 方法的重載,例如 postForObject, putForObject 等
}
  • uri():返回基礎(chǔ) URI。
  • getForObject(String url, ...):發(fā)起 GET 請求并期望獲取對象響應(yīng)。
  • getForFlux(String url, ...):發(fā)起 GET 請求并期望獲取元素流響應(yīng)。

WebClient.Builder 構(gòu)建器

WebClient 的實例是通過 WebClient.Builder 構(gòu)建的:

public final class WebClient.Builder {
    private final String baseUrl;

    public Builder(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public WebClient build() {
        return new ExchangeStrategiesDefaultWebClient(this);
    }

    // 其他配置選項,例如設(shè)置 ExchangeStrategies, ClientHttpRequestFactory 等
}
  • baseUrl:定義客戶端的基礎(chǔ) URL。

請求構(gòu)建和發(fā)送

  • 創(chuàng)建 WebClient 實例:使用 WebClient.Builder 創(chuàng)建并配置 WebClient 實例。

  • 構(gòu)建請求:使用 WebClient 的方法來添加請求頭、查詢參數(shù)、請求體等。

  • 發(fā)起請求:調(diào)用 HTTP 方法對應(yīng)的方法(如 getForObject、postForObject)來發(fā)起請求。

  • 處理響應(yīng):響應(yīng)以 Mono 或 Flux 的形式返回,可以進(jìn)一步處理。

源碼實現(xiàn)步驟

  • 配置和創(chuàng)建:通過 WebClient.Builder 配置基礎(chǔ) URL 和其他選項,然后創(chuàng)建 WebClient 實例。
WebClient webClient = WebClient.builder().baseUrl("http://example.com").build();

構(gòu)建請求:使用 WebClient 的方法鏈?zhǔn)綐?gòu)建請求。

    Mono personMono = webClient.get()
        .uri("/person/{id}", id)
        .retrieve()
        .bodyToMono(Person.class);
  • 發(fā)起請求并獲取響應(yīng):調(diào)用 retrieve() 方法并指定響應(yīng)體轉(zhuǎn)換的方式。

  • 響應(yīng)體轉(zhuǎn)換:使用 bodyToMono 或 bodyToFlux 等方法將響應(yīng)體轉(zhuǎn)換為指定類型。

  • 錯誤處理:使用 onErrorResume 或 onErrorMap 等操作符處理可能發(fā)生的錯誤。

  • 訂閱和消費:訂閱響應(yīng)體 Mono 或 Flux 并消費數(shù)據(jù)。

并發(fā)和異步處理

WebClient 支持并發(fā)和異步處理,允許以非阻塞的方式發(fā)起多個請求:

  • 使用 Flux 可以處理多個響應(yīng)。
  • 可以使用 Scheduler 來控制并發(fā)級別。

小結(jié)一下

WebClient 是 Spring WebFlux 中一個強(qiáng)大且靈活的組件,用于構(gòu)建非阻塞的響應(yīng)式 HTTP 客戶端。它允許以聲明式的方式構(gòu)建請求,并通過 Reactive Streams 規(guī)范支持異步數(shù)據(jù)處理。WebClient 的設(shè)計使得它非常適合在響應(yīng)式應(yīng)用程序中使用,可以充分利用現(xiàn)代異步編程的優(yōu)勢,提高應(yīng)用程序的性能和可伸縮性。

開發(fā)者可以輕松地使用 WebClient 與外部服務(wù)進(jìn)行通信,獲取數(shù)據(jù),并以響應(yīng)式的方式處理這些數(shù)據(jù)。通過 WebClient,Spring WebFlux 應(yīng)用程序可以無縫地集成到更大的響應(yīng)式系統(tǒng)中。

12. Spring Data Reactive

Spring Data Reactive 是 Spring Data 項目的一部分,它提供了一組用于訪問響應(yīng)式數(shù)據(jù)存儲的抽象。它允許以聲明式和響應(yīng)式的方式進(jìn)行數(shù)據(jù)訪問和操作,支持如 MongoDB、Redis、R2DBC(Reactive Relational Database Connectivity)等響應(yīng)式數(shù)據(jù)庫。以下是對 Spring Data Reactive 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

Spring Data Reactive 核心概念

  • Reactive Repository:擴(kuò)展了 Reactive Streams 規(guī)范,提供了異步的 CRUD 操作。
  • ReactiveCrudRepository:基礎(chǔ)接口,提供基本的 CRUD 操作。
  • ReactiveMongoRepository、ReactiveRedisRepository 等:特定數(shù)據(jù)庫的實現(xiàn)。

Reactive Repository 接口定義

public interface ReactiveCrudRepository extends ReactiveRepository {
    Mono save(T entity);
    Flux findAll();
    Mono findById(ID id);
    Mono deleteById(ID id);
    // 其他方法...
}
  • save(T entity):保存實體。
  • findAll():查找所有記錄。
  • findById(ID id):通過 ID 查找記錄。
  • deleteById(ID id):通過 ID 刪除記錄。

響應(yīng)式數(shù)據(jù)訪問步驟

  • 定義實體類:創(chuàng)建一個實體類,使用 JPA 注解或數(shù)據(jù)庫特定的注解標(biāo)記字段。

  • 定義倉庫接口:創(chuàng)建一個繼承自 ReactiveCrudRepository 或特定數(shù)據(jù)庫的 Repository 接口。

    public interface MyEntityRepository extends ReactiveCrudRepository {
        // 可以添加自定義查詢方法
    }
  • 配置數(shù)據(jù)源:配置響應(yīng)式數(shù)據(jù)源和客戶端,例如配置 MongoDB 的 ReactiveMongoDatabase。

  • 使用倉庫:在服務(wù)層注入并使用倉庫接口進(jìn)行數(shù)據(jù)操作。

  • 構(gòu)建查詢:使用倉庫接口提供的方法或自定義查詢方法構(gòu)建查詢。

  • 異步處理:處理查詢結(jié)果,使用 Mono 或 Flux 的異步特性。

源碼實現(xiàn)邏輯

  • 實體和倉庫定義:定義數(shù)據(jù)實體和倉庫接口。

  • Spring 應(yīng)用上下文:Spring 應(yīng)用上下文掃描倉庫接口并創(chuàng)建代理實現(xiàn)。

  • 執(zhí)行查詢:當(dāng)調(diào)用倉庫接口的方法時,代理將方法調(diào)用轉(zhuǎn)換為數(shù)據(jù)庫操作。

  • 結(jié)果封裝:查詢結(jié)果封裝在 Mono 或 Flux 中返回。

  • 錯誤處理:處理可能發(fā)生的異常,將它們轉(zhuǎn)換為合適的響應(yīng)。

  • 響應(yīng)式流控制:使用 Reactive Streams 規(guī)范控制數(shù)據(jù)流。

響應(yīng)式數(shù)據(jù)庫操作示例

@Service
public class MyEntityService {
    private final MyEntityRepository repository;

    @Autowired
    public MyEntityService(MyEntityRepository repository) {
        this.repository = repository;
    }

    public Mono addMyEntity(MyEntity entity) {
        return repository.save(entity);
    }

    public Flux getAllMyEntities() {
        return repository.findAll();
    }
}

小結(jié)一下

Spring Data Reactive 通過提供響應(yīng)式倉庫接口,簡化了響應(yīng)式數(shù)據(jù)訪問的實現(xiàn)。它利用了 Reactive Streams 規(guī)范,允許以非阻塞的方式進(jìn)行數(shù)據(jù)庫操作,提高了應(yīng)用程序的性能和可伸縮性。開發(fā)者可以輕松地定義倉庫接口,并使用 Spring 提供的 CRUD 方法或自定義查詢方法進(jìn)行數(shù)據(jù)操作。

Spring Data Reactive 組件的設(shè)計允許它與現(xiàn)代響應(yīng)式編程模型和框架(如 WebFlux)無縫集成,為構(gòu)建響應(yīng)式應(yīng)用程序提供了強(qiáng)大的數(shù)據(jù)訪問能力。通過使用 Spring Data Reactive,開發(fā)者可以構(gòu)建高效、彈性的應(yīng)用程序,同時保持代碼的簡潔性和可維護(hù)性。

13. Spring Security Reactive

Spring Security Reactive 是 Spring Security 的響應(yīng)式擴(kuò)展,它為響應(yīng)式應(yīng)用程序提供了安全和認(rèn)證支持。以下是對 Spring Security Reactive 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

Spring Security Reactive 核心概念

  • ServerSecurityContextRepository:用于在請求中存儲和檢索 SecurityContext。
  • ReactiveSecurityContextHolder:管理 SecurityContext 的持有者。
  • ServerSecurityConfigurer:用于配置安全上下文。
  • ServerHttpSecurity:定義了響應(yīng)式 HTTP 安全策略。
  • ReactiveAuthenticationManager 和 ReactiveUserDetailsService:用于用戶認(rèn)證和用戶詳情服務(wù)。

ServerSecurityContextRepository 接口定義

public interface ServerSecurityContextRepository {
    Mono save(ServerSecurityContext context);
    Mono load();
    void invalidate();
}
  • save:保存 ServerSecurityContext。
  • load:加載 ServerSecurityContext。
  • invalidate:使 ServerSecurityContext 無效。

ServerHttpSecurity 配置

public class ServerHttpSecurity {
    public ServerHttpSecurity(ReactiveAuthenticationManager authentication) {
        // ...
    }

    public SecurityWebFilterChain build() {
        // ...
    }

    public ServerHttpSecurity authorizeExchange(Consumer configurer) {
        // ...
    }

    // 其他配置方法,例如 cors, csrf, formLogin, httpBasic 等
}
  • authorizeExchange:配置授權(quán)策略。
  • build:構(gòu)建 SecurityWebFilterChain。

響應(yīng)式認(rèn)證和授權(quán)步驟

  • 配置認(rèn)證管理器:創(chuàng)建并配置 ReactiveAuthenticationManager。

  • 配置用戶服務(wù):創(chuàng)建并配置 ReactiveUserDetailsService。

  • 構(gòu)建 ServerHttpSecurity:使用 ServerHttpSecurity 構(gòu)建安全策略。

  • 配置安全上下文存儲:配置 ServerSecurityContextRepository。

  • 注冊 WebFilter:將 SecurityWebFilterChain 注冊到 Web 過濾器鏈中。

  • 處理認(rèn)證和授權(quán):在請求處理過程中,Spring Security Reactive 攔截請求并處理認(rèn)證和授權(quán)。

源碼實現(xiàn)邏輯

  • 初始化:在應(yīng)用程序啟動時,Spring Security Reactive 初始化安全配置。

  • 請求攔截:SecurityWebFilterChain 攔截請求并根據(jù)配置的安全策略進(jìn)行處理。

  • 認(rèn)證:使用 ReactiveAuthenticationManager 進(jìn)行用戶認(rèn)證。

  • 授權(quán):根據(jù) ServerHttpSecurity 配置的授權(quán)規(guī)則,使用 ReactiveAccessDecisionManager 進(jìn)行訪問控制。

  • 安全上下文:使用 ServerSecurityContextRepository 管理每個請求的安全上下文。

  • 異常處理:處理安全相關(guān)的異常,如認(rèn)證失敗或訪問拒絕。

  • 響應(yīng):根據(jù)認(rèn)證和授權(quán)的結(jié)果,構(gòu)建響應(yīng)并返回給客戶端。

小結(jié)一下

Spring Security Reactive 為響應(yīng)式應(yīng)用程序提供了全面的安全支持。它基于 Spring Security 的核心概念,并通過響應(yīng)式編程模型提供了異步、非阻塞的安全處理能力。通過 ServerHttpSecurity 的配置,開發(fā)者可以靈活地定義認(rèn)證和授權(quán)策略,以滿足不同應(yīng)用程序的安全需求。

Spring Security Reactive 的設(shè)計允許它與 Spring WebFlux 無縫集成,為響應(yīng)式 Web 應(yīng)用程序提供強(qiáng)大的安全保障。通過使用 Spring Security Reactive,開發(fā)者可以構(gòu)建安全、可靠且易于維護(hù)的響應(yīng)式應(yīng)用程序。

14. HttpHandler

HttpHandler 組件在 Spring WebFlux 中是一個用于處理 HTTP 請求的接口,它是響應(yīng)式編程模型中最低層次的 HTTP 請求處理契約。HttpHandler 作為一個共同的接口,允許不同的運行時環(huán)境通過不同的實現(xiàn)來處理 HTTP 請求。以下是對 HttpHandler 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

HttpHandler 接口定義

HttpHandler 接口定義了一個 handle 方法,用于處理傳入的 HTTP 請求并返回一個響應(yīng):

public interface HttpHandler {
    Mono handle(ServerHttpRequest request, ServerHttpResponse response);
}
handle(ServerHttpRequest request, ServerHttpResponse response):處理給定的請求并構(gòu)造響應(yīng)。

核心職責(zé)

HttpHandler 的核心職責(zé)包括:

  • 接收請求:接收 ServerHttpRequest 對象,該對象封裝了 HTTP 請求的詳細(xì)信息。
  • 構(gòu)造響應(yīng):根據(jù)請求信息構(gòu)造 ServerHttpResponse 對象,設(shè)置狀態(tài)碼、響應(yīng)頭等。
  • 返回結(jié)果:返回一個 Mono 對象,表示異步的響應(yīng)處理過程。

實現(xiàn)步驟

  • 創(chuàng)建 HttpHandler 實例:實現(xiàn) HttpHandler 接口或使用現(xiàn)有的實現(xiàn)。

  • 處理請求:在 handle 方法中編寫邏輯以處理請求,例如路由、認(rèn)證、業(yè)務(wù)處理等。

  • 構(gòu)造響應(yīng):根據(jù)請求的處理結(jié)果構(gòu)造響應(yīng),設(shè)置狀態(tài)碼、響應(yīng)頭和響應(yīng)體。

  • 返回 Mono :返回一個 Mono ,表示響應(yīng)已經(jīng)發(fā)送或?qū)⒈话l(fā)送。

  • 錯誤處理:在 handle 方法中處理可能發(fā)生的異常,確保它們被適當(dāng)?shù)剞D(zhuǎn)換為響應(yīng)。

示例實現(xiàn)

以下是一個簡單的 HttpHandler 實現(xiàn)示例,它返回一個固定的響應(yīng):

public class SimpleHttpHandler implements HttpHandler {

    @Override
    public Mono handle(ServerHttpRequest request, ServerHttpResponse response) {
        String body = "Hello, World!";
        response.getHeaders().add("Content-Type", "text/plain");
        return response.writeWith(Flux.just(DataBufferUtils.wrap(body)));
    }
}

小結(jié)一下

HttpHandler 組件是 Spring WebFlux 中用于處理 HTTP 請求的基礎(chǔ)接口。它提供了一個簡單而靈活的方式來處理 HTTP 請求和構(gòu)造響應(yīng)。通過實現(xiàn) HttpHandler 接口,開發(fā)者可以控制整個請求處理流程,包括請求解析、業(yè)務(wù)邏輯處理和響應(yīng)構(gòu)建。

HttpHandler 的實現(xiàn)可以與其他 Spring WebFlux 組件(如 DispatcherHandler、HandlerMapping、HandlerAdapter 等)結(jié)合使用,以構(gòu)建一個完整的響應(yīng)式 Web 應(yīng)用程序。這種低層次的接口為需要高度定制的 Web 應(yīng)用程序提供了強(qiáng)大的靈活性。

15. ContextPathCompositeHandler

ContextPathCompositeHandler 是 Spring WebFlux 中的一個組件,它允許在同一服務(wù)器上將多個應(yīng)用程序映射到不同的上下文路徑(context paths)。這類似于在傳統(tǒng)的 Servlet 容器中為每個 Web 應(yīng)用程序配置不同的 URL 路徑。

以下是對 ContextPathCompositeHandler 組件的源碼實現(xiàn)邏輯和步驟的詳細(xì)分析:

ContextPathCompositeHandler 接口定義

ContextPathCompositeHandler 實際上不是一個接口,而是 HandlerMapping 接口的一個實現(xiàn),它組合了多個 Handler 對象,每個對象都關(guān)聯(lián)一個上下文路徑。

主要屬性

  • contextPaths:存儲上下文路徑和對應(yīng)的 Handler 映射。
  • pattern:用于匹配請求路徑的正則表達(dá)式。

上下文路徑映射

ContextPathCompositeHandler 維護(hù)了一個映射,將每個上下文路徑映射到一個 Handler:

private final Map contextPaths = new ConcurrentHashMap<>();

添加應(yīng)用程序

應(yīng)用程序可以在初始化時通過 ContextPathCompositeHandler 的 addHandler 方法添加到映射中:

public void addHandler(String contextPath, HttpHandler handler) {
    this.contextPaths.put(contextPath, handler);
    // 更新正則表達(dá)式模式以匹配所有注冊的上下文路徑
    updatePattern();
}

處理請求

ContextPathCompositeHandler 通過 getHandler 方法來確定請求應(yīng)該由哪個 Handler 處理:

@Override
public Mono getHandler(ServerWebExchange exchange) {
    String path = extractContextPath(exchange);
    return Mono.justOrEmpty(contextPaths.get(path))
            .map(HandlerAdapter::new)
            .defaultIfEmpty(Mono.defer(() -> createNotFoundError(exchange)));
}

 
  • extractContextPath:提取請求的上下文路徑。
  • getHandler:根據(jù)上下文路徑從映射中獲取對應(yīng)的 Handler。

正則表達(dá)式模式

ContextPathCompositeHandler 使用正則表達(dá)式來匹配請求路徑:

private void updatePattern() {
    // 構(gòu)建匹配所有注冊上下文路徑的正則表達(dá)式
    String regex = contextPaths.keySet().stream()
            .map(this::toRegex)
            .collect(Collectors.joining("|", "^(", ")$"));
    this.compiledPattern = Pattern.compile(regex);
}

錯誤處理

如果沒有找到匹配的上下文路徑,ContextPathCompositeHandler 會創(chuàng)建一個表示 "Not Found" 的錯誤處理器:

private Mono createNotFoundError(ServerWebExchange exchange) {
    return Mono.just(new HandlerAdapter() {
        @Override
        public boolean supports(Object handler) {
            return true;
        }

        @Override
        public Mono handle(ServerWebExchange exchange, Object handler) {
            return ServerResponse.notFound().build().writeTo(exchange);
        }
    });
}

小結(jié)一下

ContextPathCompositeHandler 組件是 Spring WebFlux 中用于將多個應(yīng)用程序映射到不同上下文路徑的 HandlerMapping 實現(xiàn)。它通過維護(hù)一個上下文路徑到 HttpHandler 的映射,允許每個應(yīng)用程序處理其自己的請求路徑。通過正則表達(dá)式匹配請求路徑,并使用 HandlerAdapter 來適配和調(diào)用相應(yīng)的處理器。

這種設(shè)計模式使得在單個服務(wù)器實例中部署和管理多個 WebFlux 應(yīng)用程序變得簡單和高效,每個應(yīng)用程序都可以有自己的上下文路徑,而 ContextPathCompositeHandler 負(fù)責(zé)將請求路由到正確的應(yīng)用程序處理器。

最后

以上是Spring WebFlux 框架核心組件的全部介紹了,希望可以幫助你全面深入的理解 WebFlux的原理,關(guān)注【威哥愛編程】,主頁里可查看V哥每天更新的原創(chuàng)技術(shù)內(nèi)容,讓我們一起成長。

小編推薦閱讀

好特網(wǎng)發(fā)布此文僅為傳遞信息,不代表好特網(wǎng)認(rèn)同期限觀點或證實其描述。

RPG Ri序章 0.2.1
RPG Ri序章 0.2.1
類型:角色扮演  運營狀態(tài):正式運營  語言: 日文  

游戲攻略

游戲禮包

游戲視頻

游戲下載

游戲活動

《RPG_Ri序章》是GameMaker'Child-Dream'制作的一款幻想廢土風(fēng)RPG手游,完全免費的幻想廢土風(fēng)RPG登場!元
核心
核心
類型:休閑益智  運營狀態(tài):正式運營  語言: 英文   

游戲攻略

游戲禮包

游戲視頻

游戲下載

游戲活動

《核心》(CORE)是游戲商FURYJAM旗下的一款休閑益智手游,游戲中,玩家將控制發(fā)光的白色小核心,穿過各

相關(guān)視頻攻略

更多

掃二維碼進(jìn)入好特網(wǎng)手機(jī)版本!

掃二維碼進(jìn)入好特網(wǎng)微信公眾號!

本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請發(fā)郵件[email protected]

湘ICP備2022002427號-10 湘公網(wǎng)安備:43070202000427號© 2013~2025 haote.com 好特網(wǎng)