Spring Webflux HttpHandler源码整理

HttpHandler的构造
  1. 自动启动配置类:HttpHandlerAutoConfiguration

    text 复制代码
    @Bean
    public HttpHandler httpHandler(ObjectProvider<WebFluxProperties> propsProvider) {
        HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();
        WebFluxProperties properties = propsProvider.getIfAvailable();
        if (properties != null && StringUtils.hasText(properties.getBasePath())) {
            Map<String, HttpHandler> handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler);
            return new ContextPathCompositeHandler(handlersMap);
        }
       return httpHandler;
    }
  2. ApplicationContext.applicationContext

    text 复制代码
    获取spring容器中的WebHandler并保存到WebHttpHandlerBuilder中 (这里传入的WebHandler为DispatcherHandler实例)
    获取spring容器中的WebFilter并保存到WebHttpHandlerBuilder中
    获取spring容器中的WebExceptionHandler并保存到WebHttpHandlerBuilder中
    获取spring容器中的HttpHandlerDecoratorFactory并保存到WebHttpHandlerBuilder中
    获取spring容器中WebSessionManager并保存到WebHttpHandlerBuilder中
    ...
  3. WebHttpHandlerBuilder#build构建HttpHandler

    text 复制代码
    public HttpHandler build() {
       WebHandler decorated = new FilteringWebHandler(this.webHandler, this.filters);
       decorated = new ExceptionHandlingWebHandler(decorated,  this.exceptionHandlers);
       HttpWebHandlerAdapter adapted = new HttpWebHandlerAdapter(decorated);
       adapted.setSessionManager(this.sessionManager);
       adapted.setCodecConfigurer(this.codecConfigurer);
       adapted.setLocaleContextResolver(this.localeContextResolver);
       adapted.setForwardedHeaderTransformer(this.forwardedHeaderTransformer);
       adapted.setApplicationContext(this.applicationContext);
       adapted.afterPropertiesSet();
       return (this.httpHandlerDecorator != null ? this.httpHandlerDecorator.apply(adapted) : adapted);
    }
  4. 实例化FilteringWebHandler

    text 复制代码
    public FilteringWebHandler(WebHandler handler, List<WebFilter> filters) {
        this.delegate = handler;
        this.chain = new DefaultWebFilterChain(handler, filters);
    }
  5. 实例化DefaultWebFilterChain

    text 复制代码
    public DefaultWebFilterChain(WebHandler handler, List<WebFilter> filters) {
         this.allFilters = Collections.unmodifiableList(filters);
         this.handler = handler;
         DefaultWebFilterChain chain = initChain(filters, handler);
         this.currentFilter = chain.currentFilter;
         this.chain = chain.chain;
     }
  6. initChain代码片段

    text 复制代码
     private static DefaultWebFilterChain initChain(List<WebFilter> filters, WebHandler handler) {
         DefaultWebFilterChain chain = new DefaultWebFilterChain(filters, handler, null, null);
         ListIterator<? extends WebFilter> iterator = filters.listIterator(filters.size());
         while (iterator.hasPrevious()) {
             chain = new DefaultWebFilterChain(filters, handler, iterator.previous(), chain);
         }
         return chain;
     }
HttpHandler的执行
  1. HttpWebHandlerAdapter#handle执行

    text 复制代码
    public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
       ServerWebExchange exchange = createExchange(request, response);
       return getDelegate().handle(exchange)
           .doOnSuccess(aVoid -> logResponse(exchange))
           .onErrorResume(ex -> handleUnresolvedError(exchange, ex))
           .then(Mono.defer(response::setComplete));
    }
  2. ExceptionHandlingWebHandler#handle(exchange)执行

    text 复制代码
    public Mono<Void> handle(ServerWebExchange exchange) {
         Mono<Void> completion;
         try {
             completion = super.handle(exchange);
         }catch (Throwable ex) {
             completion = Mono.error(ex);
         }
         for (WebExceptionHandler handler : this.exceptionHandlers) {
             completion = completion.onErrorResume(ex -> handler.handle(exchange, ex));
         }
         return completion;
    }
  3. FilteringWebHandler#handle

    text 复制代码
    public Mono<Void> handle(ServerWebExchange exchange) {
      return this.chain.filter(exchange);
    }
  4. DefaultWebFilterChain#filter执行

    text 复制代码
     public Mono<Void> filter(ServerWebExchange exchange) {
         return Mono.defer(() ->
              this.currentFilter != null && this.chain != null ?
                   invokeFilter(this.currentFilter, this.chain, exchange) :
                   this.handler.handle(exchange));
     }
     private Mono<Void> invokeFilter(WebFilter current, DefaultWebFilterChain chain, ServerWebExchange exchange) {
         String currentName = current.getClass().getName();
         return current.filter(exchange, chain).checkpoint(currentName + " [DefaultWebFilterChain]");
     }
  5. DispatcherHandler#handle执行

相关推荐
Full Stack Developme37 分钟前
Java LRU 与 LFU 算法及应用
java·开发语言·算法
IT_陈寒2 小时前
闭包陷阱让我加了两天班,JavaScript你真行
前端·人工智能·后端
易协同低代码3 小时前
通达OA核心类库TD类深度解析
后端
Gopher_HBo3 小时前
Go语言学习笔记(十八)Gin处理Session
后端
谭光志4 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
shushangyun_4 小时前
2026智能采购商城系统选型指南:如何引领企业数字化采购升级
java·大数据·数据库·人工智能·机器学习
她说..4 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
foggyprojects4 小时前
从0开始,一句话启动AI DataAgent
后端·数据分析·ai编程
郡杰4 小时前
一些基础和问题解决
后端
陈随易4 小时前
前端项目部署只要30秒
前端·后端·程序员