You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring WebFlux请求响应生命周期钩子添加及起止位置确认

Measuring Full Request-Response Lifecycle in Spring WebFlux: Correct Hook Points

Great question—capturing the full request-response lifecycle in reactive frameworks like WebFlux can feel counterintuitive at first, but your initial approach with WebFilter is spot-on. Let’s clarify the right hook points and address your concerns:

Starting Point: First WebFilter is Perfect

Placing your start logic before calling WebFilterChain.filter(exchange) is exactly the right move. As the first filter in the chain, this is the earliest point Spring begins processing the request (right after container-level handling like Tomcat/Netty accepts the connection). This ensures you capture the true start of the request’s journey through your application.

Ending Point: doOnSuccessOrError on the Filter Chain Mono

Your hunch about using doOnSuccessOrError is correct, and it does fire after all downstream processing—including HandlerResultHandler execution and full response body (even chunked) delivery. Here’s why:

  • The Mono<Void> returned by chain.filter(exchange) only completes when the entire reactive processing chain finishes. That includes:
    1. All downstream filters executing
    2. Controller handler method running
    3. HandlerResultHandler converting the handler’s result into a response
    4. All response data (including final chunks in streaming scenarios) being written to the client

Example Implementation

Here’s a concrete, clean way to implement this:

@Component
public class RequestTimingFilter implements WebFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        long startTime = System.currentTimeMillis();
        String path = exchange.getRequest().getPath().value();

        return chain.filter(exchange)
                .doOnSuccess(v -> {
                    long duration = System.currentTimeMillis() - startTime;
                    int status = exchange.getResponse().getStatusCode().value();
                    System.out.printf("Request %s completed in %dms with status %d%n", path, duration, status);
                })
                .doOnError(error -> {
                    long duration = System.currentTimeMillis() - startTime;
                    System.err.printf("Request %s failed in %dms: %s%n", path, duration, error.getMessage());
                });
    }
}

Key Notes for Chunked/Streaming Responses

For chunked responses (like ServerSentEvent or streaming JSON), the Mono<Void> from chain.filter(exchange) will only complete when the entire stream is exhausted and the last chunk is sent to the client. This means your doOnSuccess callback will trigger exactly when the full response is delivered—exactly what you need.

Why This Works Over Other Hooks

  • Avoid using doOnComplete alone: It won’t capture error scenarios, so doOnSuccessOrError gives you full coverage for both success and failure lifecycles.
  • This hook is container-agnostic: It works with any reactive web container (Netty, Tomcat, Jetty) since it’s part of Spring WebFlux’s native filter chain.

Final Verdict

Your initial plan is solid:

  • Start: Immediately before invoking chain.filter(exchange) in your first WebFilter
  • End: On doOnSuccessOrError attached to the Mono returned by chain.filter(exchange)

This setup will accurately measure the full request-response lifecycle, from the moment Spring starts processing the request to the moment the last byte of the response is sent to the client.

内容的提问来源于stack exchange,提问作者anuni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:35:09