SpringCloud Gateway DispatcherHandler
Polarisy丶 人气:0前言
之前几节我们分析了请求是如何调用到HttpWebHandlerAdapter
的,然后再调用到DispatcherHandler
中,通过handle方法来处理具体的请求。
DispatcherHandler的注入在自动装配那一节已经说过了,忘记的同学可以重新会看一下。
DispatcherHandler类声明
public class DispatcherHandler implements WebHandler, PreFlightRequestHandler, ApplicationContextAware {
可以看到实现了ApplicationContextAware
接口,并实现了setApplicationContext
方法
@Override public void setApplicationContext(ApplicationContext applicationContext) { initStrategies(applicationContext); }
protected void initStrategies(ApplicationContext context) { Map<String, HandlerMapping> mappingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors( context, HandlerMapping.class, true, false); ArrayList<HandlerMapping> mappings = new ArrayList<>(mappingBeans.values()); AnnotationAwareOrderComparator.sort(mappings); this.handlerMappings = Collections.unmodifiableList(mappings); Map<String, HandlerAdapter> adapterBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors( context, HandlerAdapter.class, true, false); this.handlerAdapters = new ArrayList<>(adapterBeans.values()); AnnotationAwareOrderComparator.sort(this.handlerAdapters); Map<String, HandlerResultHandler> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors( context, HandlerResultHandler.class, true, false); this.resultHandlers = new ArrayList<>(beans.values()); AnnotationAwareOrderComparator.sort(this.resultHandlers); }
可以看到,这里初始化了核心的三部分内容,具体是handlerMappings
,handlerAdapters
,resultHandlers
通过名字我们可以猜想它们的具体作用,后面会详细解析
- 通过handlerMappings确定具体处理网关请求的handler
- 通过handlerAdapters确定具体支持处理handler的handlerAdapter,并处理handler。因为负责处理请求的方式不只一种,可以是注解的方法,也可以是函数式接口(lambda 表达式),也就是通过handlerMappings映射返回的对象是不一样的, 要把它们适配成统一的API。
- 最终由resultHandler生成返回结果
handle方法
接下来我们来看下最核心的handle方法是如何具体处理请求的
@Override public Mono<Void> handle(ServerWebExchange exchange) { if (this.handlerMappings == null) { return createNotFoundError(); } if (CorsUtils.isPreFlightRequest(exchange.getRequest())) { return handlePreFlight(exchange); } //循环遍历所有的handlerMappings通过getHandler找到具体的handler return Flux.fromIterable(this.handlerMappings) .concatMap(mapping -> mapping.getHandler(exchange)) //next方法表示如果循环遍历handlerMappings时有多个匹配的handler,通过next方法只取出第一个匹配的handler执行下面的调用方法 .next() .switchIfEmpty(createNotFoundError()) //处理具体的handler .flatMap(handler -> invokeHandler(exchange, handler)) //处理结果 .flatMap(result -> handleResult(exchange, result)); }
首先看getHandler方法
AbstractHandlerMapping.java @Override public Mono<Object> getHandler(ServerWebExchange exchange) { return getHandlerInternal(exchange).map(handler -> { if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + "Mapped to " + handler); } ServerHttpRequest request = exchange.getRequest(); if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) { CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(exchange) : null); CorsConfiguration handlerConfig = getCorsConfiguration(handler, exchange); config = (config != null ? config.combine(handlerConfig) : handlerConfig); if (config != null) { config.validateAllowCredentials(); } if (!this.corsProcessor.process(config, exchange) || CorsUtils.isPreFlightRequest(request)) { return NO_OP_HANDLER; } } return handler; }); }
其中会调用getHandlerInternal方法,是一个抽象方法
protected abstract Mono<?> getHandlerInternal(ServerWebExchange exchange);
通过断点调试可以看到,其中handlerMappings一共有四个
getHandlerInternal方法具体实现
可以分别去每个实现方法中断点查看不难找到RoutePredicateHandlerMapping
就是我们需要的,通过名字可以猜到就是用来处理路由转发的
找到它的getHandlerInternal实现方法
@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()); //lookupRoute方法将根据配置文件中指定的predicates断言器和请求路径做匹配,如果匹配成功就会返回FilteringWebHandler 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); //上面定义的,private final FilteringWebHandler webHandler; 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) + "]"); } }))); }
lookupRoute关于路由相关的以后单独再讲,现在知道了返回的handler就是FilteringWebHandler
下面关注invokeHandler方法
private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) { if (ObjectUtils.nullSafeEquals(exchange.getResponse().getStatusCode(), HttpStatus.FORBIDDEN)) { return Mono.empty(); // CORS rejection } //遍历所有的handlerAdapters找到能够支持当前handler的handlerAdapter,并执行handle方法 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)); }
可以看到supports方法具体有四个实现
@Override public boolean supports(Object handler) { return handler instanceof HandlerFunction; } @Override public boolean supports(Object handler) { return handler instanceof HandlerMethod; } @Override public boolean supports(Object handler) { return WebHandler.class.isAssignableFrom(handler.getClass()); } @Override public boolean supports(Object handler) { return WebSocketHandler.class.isAssignableFrom(handler.getClass()); }
我们目前支持的就是WebHandler
,也就是会执行SimpleHandlerAdapter
中的handle方法
@Override public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) { //FilteringWebHandler WebHandler webHandler = (WebHandler) handler; Mono<Void> mono = webHandler.handle(exchange); return mono.then(Mono.empty()); }
之后会执行FilteringWebHandler
的handle方法
@Override public Mono<Void> handle(ServerWebExchange exchange) { //找到该请求对应的路由 Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR); //找到该路由对应的GatewayFilter List<GatewayFilter> gatewayFilters = route.getFilters(); //得到全局的的GatewayFilter 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); } //生成Gateway过滤器链,然后对客户端请求进行处理 return new DefaultGatewayFilterChain(combined).filter(exchange); }
首先先看一下FilteringWebHandler
在哪被注入的,通过搜索发现在GatewayAutoConfiguration
中注入的
@Bean public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) { return new FilteringWebHandler(globalFilters); }
通过调试可以看到注入所有的GlobalFilter
,默认有10个,并初始化
public FilteringWebHandler(List<GlobalFilter> globalFilters) { //初始化时加载所有全局过滤器,将他们适配为GatewayFilter类型,方便等会做合并 this.globalFilters = loadFilters(globalFilters); } //适配器模式,通过嵌套把GlobalFilter封装成GatewayFilter类型 private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) { return filters.stream().map(filter -> { //GatewayFilterAdapter持有GlobalFilter对象 GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter); if (filter instanceof Ordered) { //将后续用来排序的order值传进来 int order = ((Ordered) filter).getOrder(); //OrderedGatewayFilter同样持有GatewayFilter对象 return new OrderedGatewayFilter(gatewayFilter, order); } return gatewayFilter; }).collect(Collectors.toList()); }
至于这里为什么要返回两种不同的对象分别持有GatewayFilter
,主要和后面的排序相关
对于实现了Ordered
接口的filter会返回OrderedGatewayFilter
对象
接着回到前面的handle方法中,其中有一步就是用来排序的
AnnotationAwareOrderComparator.sort(combined);
通过调试可以找到具体的实现在OrderComparator
中
@Override public int compare(@Nullable Object o1, @Nullable Object o2) { return doCompare(o1, o2, null); } private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) { //谁实现了PriorityOrdered接口就代表谁的优先级高 boolean p1 = (o1 instanceof PriorityOrdered); boolean p2 = (o2 instanceof PriorityOrdered); if (p1 && !p2) { return -1; } else if (p2 && !p1) { return 1; } int i1 = getOrder(o1, sourceProvider); int i2 = getOrder(o2, sourceProvider); return Integer.compare(i1, i2); }
如果都实现了PriorityOrdered
接口或者都没有实现,那么通过getOrder方法得到的值来排序
private int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) { Integer order = null; if (obj != null && sourceProvider != null) { Object orderSource = sourceProvider.getOrderSource(obj); if (orderSource != null) { if (orderSource.getClass().isArray()) { for (Object source : ObjectUtils.toObjectArray(orderSource)) { order = findOrder(source); if (order != null) { break; } } } else { order = findOrder(orderSource); } } } return (order != null ? order : getOrder(obj)); }
传入的sourceProvider为null,最终调用另外一个getOrder方法
protected int getOrder(@Nullable Object obj) { if (obj != null) { Integer order = findOrder(obj); if (order != null) { return order; } } return Ordered.LOWEST_PRECEDENCE; }
进入findOrder方法
@Nullable protected Integer findOrder(Object obj) { return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null); }
可以看到,如果实现了Ordered
接口,则调用重写的getOrder方法,否则返回null,最后会返回
Ordered.LOWEST_PRECEDENCE,代表最低的优先级
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
后面通过Integer.compare方法来比较,值越大的优先级越低
最后总结一下
- 谁实现了
PriorityOrdered
接口就代表谁的优先级高 - 如果都没有实现或者都实现了,那么判断是否实现了
Ordered
接口 - 如果实现了
Ordered
接口,那么返回实现方法中getOrder的值 - 如果没有实现
Ordered
接口,那么返回最低的优先级也就是Integer的最大值 - 最后在比较两个值的大小,值越大代表优先级越小,值越小代表优先级越大
加载全部内容