• Spring Webflux DispatcherHandler源码整理


    DispatcherHandler的构造(以RequestMappingHandlerMapping为例)
    1. WebFluxAutoConfiguration中EnableWebFluxConfiguration继承WebFluxConfigurationSupport
      @Bean
      public DispatcherHandler webHandler() {
          return new DispatcherHandler();
      }
      
      • 1
      • 2
      • 3
      • 4
    2. DispatcherHandler#setApplicationContext => initStrategies(applicationContext)
      protected void initStrategies(ApplicationContext context) {
          Map mappingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                  context, HandlerMapping.class, true, false);
          ArrayList mappings = new ArrayList<>(mappingBeans.values());
          AnnotationAwareOrderComparator.sort(mappings);
          this.handlerMappings = Collections.unmodifiableList(mappings);
          //
          Map adapterBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                  context, HandlerAdapter.class, true, false);
          //
          this.handlerAdapters = new ArrayList<>(adapterBeans.values());
          AnnotationAwareOrderComparator.sort(this.handlerAdapters);
          //
          Map beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                  context, HandlerResultHandler.class, true, false);
          this.resultHandlers = new ArrayList<>(beans.values());
          AnnotationAwareOrderComparator.sort(this.resultHandlers);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    3. RequestMappingHandlerMapping-> afterPropertiesSet -> AbstractHandlerMethodMapping.initHandlerMethods
      protected void initHandlerMethods() {
           String[] beanNames = obtainApplicationContext().getBeanNamesForType(Object.class);
           for (String beanName : beanNames) {
               if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
                   Class beanType = obtainApplicationContext().getType(beanName);
                   // 当类被Controller或则RequestMapping标注时查找HandlerMethod
                   if (beanType != null && isHandler(beanType)) {
                       detectHandlerMethods(beanName);
                   }
               }
           }
       }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    4. AbstractHandlerMethodMapping#detectHandlerMethods(beanName)
       protected void detectHandlerMethods(final Object handler) {
           Class handlerType = (handler instanceof String ?
                   obtainApplicationContext().getType((String) handler) : handler.getClass());
           if (handlerType != null) {
               final Class userType = ClassUtils.getUserClass(handlerType);
               Map methods = MethodIntrospector.selectMethods(userType,
                       (MethodIntrospector.MetadataLookup) method -> getMappingForMethod(method, userType));
               methods.forEach((method, mapping) -> {
                   Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
                   // invocableMethod保存到MappingRegistry注册表中
                   registerHandlerMethod(handler, invocableMethod, mapping);
               });
           }
       }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    5. RequestMappingHandlerMapping#getMappingForMethod(method, handlerType)
      protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) {
           RequestMappingInfo info = createRequestMappingInfo(method);
           if (info != null) {
               RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
               if (typeInfo != null) {
                   info = typeInfo.combine(info);
               }
               for (Map.Entry>> entry : this.pathPrefixes.entrySet()) {
                   if (entry.getValue().test(handlerType)) {
                       String prefix = entry.getKey();
                       if (this.embeddedValueResolver != null) {
                           prefix = this.embeddedValueResolver.resolveStringValue(prefix);
                       }
                       info = RequestMappingInfo.paths(prefix).options(this.config).build().combine(info);
                       break;
                   }
               }
           }
           return info;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    6. RequestMappingHandlerMapping#createRequestMappingInfo(method)
      private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
           RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
           RequestCondition condition = (element instanceof Class ?
                   getCustomTypeCondition((Class) element) : getCustomMethodCondition((Method) element));
           return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
      }
      protected RequestMappingInfo createRequestMappingInfo(
       		RequestMapping requestMapping, @Nullable RequestCondition customCondition) {
       	RequestMappingInfo.Builder builder = RequestMappingInfo
       			.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
       			.methods(requestMapping.method())
       			.params(requestMapping.params())
       			.headers(requestMapping.headers())
       			.consumes(requestMapping.consumes())
       			.produces(requestMapping.produces())
       			.mappingName(requestMapping.name());
       	if (customCondition != null) {
       		builder.customCondition(customCondition);
       	}
       	return builder.options(this.config).build();
       }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    DispatcherHandler的执行(以RequestMappingHandlerMapping为例)
    查找handler
    1. DispatcherHandler#handle(exchange)
      public Mono handle(ServerWebExchange exchange) {
          if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {
              return handlePreFlight(exchange);
          }
          return Flux.fromIterable(this.handlerMappings)
                  .concatMap(mapping -> mapping.getHandler(exchange))
                  .next()
                  .switchIfEmpty(createNotFoundError())
                  .flatMap(handler -> invokeHandler(exchange, handler))
                  .flatMap(result -> handleResult(exchange, result));
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    2. AbstractHandlerMapping#getHandler(exchange)
      public Mono getHandler(ServerWebExchange exchange) {
          return getHandlerInternal(exchange) ;
      }
      
      • 1
      • 2
      • 3
    3. AbstractHandlerMethodMapping#getHandlerInternal
      public Mono getHandlerInternal(ServerWebExchange exchange) {
          this.mappingRegistry.acquireReadLock();
          try {
              HandlerMethod handlerMethod;
              try {
                  handlerMethod = lookupHandlerMethod(exchange);
              }catch (Exception ex) {
                  return Mono.error(ex);
              }
              if (handlerMethod != null) {
                  handlerMethod = handlerMethod.createWithResolvedBean();
              }
              return Mono.justOrEmpty(handlerMethod);
          }finally {
              this.mappingRegistry.releaseReadLock();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
    4. AbstractHandlerMethodMapping#lookupHandlerMethod(exchange)
      protected HandlerMethod lookupHandlerMethod(ServerWebExchange exchange) throws Exception {
           List matches = new ArrayList<>();
           List directPathMatches = this.mappingRegistry.getMappingsByDirectPath(exchange);
           if (directPathMatches != null) {
               addMatchingMappings(directPathMatches, matches, exchange);
           }
           // 省略部分代码
           if (!matches.isEmpty()) {
               Comparator comparator = new MatchComparator(getMappingComparator(exchange));
               matches.sort(comparator);
               Match bestMatch = matches.get(0);
               handleMatch(bestMatch.mapping, bestMatch.getHandlerMethod(), exchange);
               return bestMatch.getHandlerMethod();
           }
           else {
               return handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), exchange);
           }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    5. 执行handler
      1. DispatcherHandler#invokeHandler
        private Mono invokeHandler(ServerWebExchange exchange, Object handler) {
             for (HandlerAdapter handlerAdapter : this.handlerAdapters) {
                 if (handlerAdapter.supports(handler)) {
                     return handlerAdapter.handle(exchange, handler);
                 }
             }
             return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
      2. RequestMappingHandlerAdapter#handle(exchange, handler)
        public Mono handle(ServerWebExchange exchange, Object handler) {
             HandlerMethod handlerMethod = (HandlerMethod) handler;
             InitBinderBindingContext bindingContext = new InitBinderBindingContext(
                     getWebBindingInitializer(), this.methodResolver.getInitBinderMethods(handlerMethod));
             InvocableHandlerMethod invocableMethod = this.methodResolver.getRequestMappingMethod(handlerMethod);
             //
             Function> exceptionHandler =
                     ex -> handleException(ex, handlerMethod, bindingContext, exchange);
             //
             return this.modelInitializer
                  .initModel(handlerMethod, bindingContext, exchange)
                  .then(Mono.defer(() -> invocableMethod.invoke(exchange, bindingContext)))
                  .doOnNext(result -> result.setExceptionHandler(exceptionHandler))
                  .doOnNext(result -> bindingContext.saveModel())
                  .onErrorResume(exceptionHandler);
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
      3. InvocableHandlerMethod#invoke
        public Mono invoke(
                 ServerWebExchange exchange, BindingContext bindingContext, Object... providedArgs) {
             return getMethodArgumentValues(exchange, bindingContext, providedArgs).flatMap(args -> {
                 Object value;
                 Method method = getBridgedMethod();
                 if (KotlinDetector.isSuspendingFunction(method)) {
                     value = CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args);
                 }else {
                     value = method.invoke(getBean(), args);
                 }
                 // 省略部分代码
                 HttpStatus status = getResponseStatus();
                 if (status != null) {
                     exchange.getResponse().setStatusCode(status);
                 }
                 MethodParameter returnType = getReturnType();
                 ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(returnType.getParameterType());
                 boolean asyncVoid = isAsyncVoidReturnType(returnType, adapter);
                 if ((value == null || asyncVoid) && isResponseHandled(args, exchange)) {
                     return (asyncVoid ? Mono.from(adapter.toPublisher(value)) : Mono.empty());
                 }
                 HandlerResult result = new HandlerResult(this, value, returnType, bindingContext);
                 return Mono.just(result);
             });
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
      处理返回结果
      1. DispatcherHandler#handleResult
        private Mono handleResult(ServerWebExchange exchange, HandlerResult result) {
            return getResultHandler(result).handleResult(exchange, result) ;
        }
        
        • 1
        • 2
        • 3
      2. DispatcherHandler#getResultHandler => ResponseBodyResultHandler
      3. ResponseBodyResultHandler#handleResult(exchange, result)
        public Mono handleResult(ServerWebExchange exchange, HandlerResult result) {
            Object body = result.getReturnValue();
            MethodParameter bodyTypeParameter = result.getReturnTypeSource();
            return writeBody(body, bodyTypeParameter, exchange);
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
    6. 相关阅读:
      Day28_vuex模块化+namespaced_2
      汇智知了堂携手西华大学共探鸿蒙生态发展之路
      Java面试时,你被深挖过什么问题?
      (01)ORB-SLAM2源码无死角解析-(38) EPnP 源代码分析(1)→PnPsolver总体流程与思路
      docker套娃实践(待续)
      模型剪枝算法——L1正则化BN层的γ因子
      筛质数(埃氏筛+欧拉筛)
      第一天:java基础复习(1)
      Pytorch学习笔记(9)——一文搞懂如何使用 torch 中的乘法
      阿里云/腾讯云国际站代理:腾讯云国际站开户购买EdgeOne发布,安全加速一体化方案获业内认可
    7. 原文地址:https://blog.csdn.net/yichengjie_c/article/details/133527150