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执行

相关推荐
方圆想当图灵10 分钟前
缓存之美:万文详解 Caffeine 实现原理(下)
java·redis·缓存
栗豆包24 分钟前
w175基于springboot的图书管理系统的设计与实现
java·spring boot·后端·spring·tomcat
等一场春雨1 小时前
Java设计模式 十四 行为型模式 (Behavioral Patterns)
java·开发语言·设计模式
萧若岚1 小时前
Elixir语言的Web开发
开发语言·后端·golang
Channing Lewis1 小时前
flask实现重启后需要重新输入用户名而避免浏览器使用之前已经记录的用户名
后端·python·flask
Channing Lewis1 小时前
如何在 Flask 中实现用户认证?
后端·python·flask
酱学编程2 小时前
java中的单元测试的使用以及原理
java·单元测试·log4j
我的运维人生2 小时前
Java并发编程深度解析:从理论到实践
java·开发语言·python·运维开发·技术共享
一只爱吃“兔子”的“胡萝卜”2 小时前
2.Spring-AOP
java·后端·spring
HappyAcmen2 小时前
Java中List集合的面试试题及答案解析
java·面试·list