6. handle 方法详解-HandlerAdapter获取及后续请求处理

1.概览

      本节是gateway入口DispatcherHandler.handle()方法原理分享的第三节也是最后一节,本节主要分享handle方法内部逻辑中的invokeHandler(exchange,handler)方法的实现原理及后续请求的处理。

2. handle方法回顾

      为了方便分享,我还是把handle方法的源码展示如下:

@Override
public Mono<Void> handle(ServerWebExchange exchange) {
   if (this.handlerMappings == null) {
      return createNotFoundError();
   }
   return Flux.fromIterable(this.handlerMappings)
         .concatMap(mapping -> mapping.getHandler(exchange))
         .next()
         .switchIfEmpty(createNotFoundError())
         .flatMap(handler -> invokeHandler(exchange, handler))
         .flatMap(result -> handleResult(exchange, result));
}

      上一节我分享mapping.getHandler(exchange)内部的实现原理,介绍handler是如何获取的,本节分享invokeHandler(exchange,Handler)方法,看一下它内部是如何实现的。

3. invokeHandler实现原理

      invokeHandler内部判断handlerAdapters是否为null,如果不为null,迭代handlerAdapters列表,判断handlerAdapter是否支持handler,如果能够处理handler,则调用handle方法,进行业务处理,代码如下:

private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {
   if (this.handlerAdapters != null) {
      for (HandlerAdapter handlerAdapter : this.handlerAdapters) {
         if (handlerAdapter.supports(handler)) {
            return handlerAdapter.handle(exchange, handler);
         }
      }
   }
   return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
}

3.1 handlerAdapters

      handlerAdapters是在DispatcherHandler内部的initStrategies方法中实例化的,具体内容可以参考前面章节。
      在我的系统中,adapter共有三个实例,如图所示:
在这里插入图片描述
他们都是HandlerAdapter的子类,HandlerAdapter共有四个子类,它的类继承关系如下图所示:
在这里插入图片描述

3.2 handlerAdapters实例化

      上节中讲述的adapters都是在WebFluxConfigurationSupport类中实例化的,实例化代码如下:

@Bean
public HandlerFunctionAdapter handlerFunctionAdapter() {
   return new HandlerFunctionAdapter();
}
@Bean
public SimpleHandlerAdapter simpleHandlerAdapter() {
   return new SimpleHandlerAdapter();
}
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
      @Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
      ServerCodecConfigurer serverCodecConfigurer,
      @Qualifier("webFluxConversionService") FormattingConversionService conversionService,
      @Qualifier("webFluxValidator") Validator validator) {

   RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
   adapter.setMessageReaders(serverCodecConfigurer.getReaders());
   adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(conversionService, validator));
   adapter.setReactiveAdapterRegistry(reactiveAdapterRegistry);

   ArgumentResolverConfigurer configurer = new ArgumentResolverConfigurer();
   configureArgumentResolvers(configurer);
   adapter.setArgumentResolverConfigurer(configurer);

   return adapter;
}

3.3 handlerAdapter.supports(handler)

      我们分别看下这四个adapter的supports方法,代码分别如下所示:
      HandlerFunctionAdapter 类中,supports判断handler是否是HandlerFunction的实例。

@Override
public boolean supports(Object handler) {
   return handler instanceof HandlerFunction;
}

      ReqiestMappingHandlerAdapter类中,supports判断handler是否是HandlerMethod的实例

@Override
public boolean supports(Object handler) {
   return handler instanceof HandlerMethod;
}

      SimpleHandlerAdapter类中,supports方法判断handler是否是WebHandler的子类。

@Override
public boolean supports(Object handler) {
   return WebHandler.class.isAssignableFrom(handler.getClass());
}

      WebSocketHandlerAdapter类中,supports方法判断handler是否是WebSocketHandler的子类。

@Override
public boolean supports(Object handler) {
   return WebSocketHandler.class.isAssignableFrom(handler.getClass());
}
isAssignableFrom()方法是判断是否为某个类的父类
父类.class.isAssignableFrom(子类.class)

3.3.1 handler 类型

      上一节分享的内容中,我分享到mapping.getHandler(exchange)方法中,mapping使用的是RoutePredicateHandlerMapping,它的getHandlerInternal方法的源代码如下:

private final FilteringWebHandler webHandler;

@Override
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
   // don't handle requests on management port if set and different than server port
   if (this.managementPortType == DIFFERENT && this.managementPort != null
         && exchange.getRequest().getURI().getPort() == this.managementPort) {
      return Mono.empty();
   }
   exchange.getAttributes().put(GATEWAY_HANDLER_MAPPER_ATTR, getSimpleName());

   return lookupRoute(exchange)
         // .log("route-predicate-handler-mapping", Level.FINER) //name this
         .flatMap((Function<Route, Mono<?>>) r -> {
            exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
            if (logger.isDebugEnabled()) {
               logger.debug(
                     "Mapping [" + getExchangeDesc(exchange) + "] to " + r);
            }

            exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, r);
            return Mono.just(webHandler);//此行
         }).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
            exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
            if (logger.isTraceEnabled()) {
               logger.trace("No RouteDefinition found for ["
                     + getExchangeDesc(exchange) + "]");
            }
         })));
}

      getHandlerInternal方法返回的是webHandler,它的类型是FilteringWebHandler,从此可知,invokeHandler(exchange, handler)使用的是SimpleHandlerAdapter的对应方法。

4 SimpleHandlerAdapter

      SimpleHandlerAdapter类的handle方法如下所示,它调用webHandler,也就是FilteringWebHandler的handle方法处理请求。

@Override
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
   WebHandler webHandler = (WebHandler) handler;
   Mono<Void> mono = webHandler.handle(exchange);
   return mono.then(Mono.empty());
}

4.1 FilteringWebHandler.handle

      FilteringWebHandler.handle方法内部获取所有的globalFilters组织成combined,排序combined,作为DefaultGatewayFilterChain的参数传入DefaultGatewayFilterChain中并且调用它的filter方法处理请求。

@Override
public Mono<Void> handle(ServerWebExchange exchange) {
   Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
   List<GatewayFilter> gatewayFilters = route.getFilters();

   List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
   combined.addAll(gatewayFilters);
   // TODO: needed or cached?
   AnnotationAwareOrderComparator.sort(combined);

   if (logger.isDebugEnabled()) {
      logger.debug("Sorted gatewayFilterFactories: " + combined);
   }

   return new DefaultGatewayFilterChain(combined).filter(exchange);
}

4.2 DefaultGatewayFilterChain.filter

      DefaultGatewayFilterChain.filter逐个调用链上的filter,对请求进行处理,代码如下:

@Override
public Mono<Void> filter(ServerWebExchange exchange) {
   return Mono.defer(() -> {
      if (this.index < filters.size()) {
         GatewayFilter filter = filters.get(this.index);
         DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this,
               this.index + 1);
         return filter.filter(exchange, chain);
      }
      else {
         return Mono.empty(); // complete
      }
   });
}

5. 总结

      本节我分享了handle方法内部HandlerAdapter获取的原理,及获取到handler后的请求处理流程,分享了gateway中filter链的执行原理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值