系列文章
Spring-Cloud-Gateway-01-网关基本概念
Spring-Cloud-Gateway-02-请求调用基本流程
Spring-Cloud-Gateway-03-网关自动装配
Spring-Cloud-Gateway-04-HttpWebHandlerAdapter到DispatcherHandler调用流程
Spring-Cloud-Gateway-05-请求到HttpWebHandlerAdapter的调用链路
Spring-Cloud-Gateway-06-DispatcherHandler调用解析
Spring-Cloud-Gateway-07-GatewayFilterChain的执行过程
Spring-Cloud-Gateway-08-路由的自动装配与加载流程
Spring-Cloud-Gateway-09-动态路由与自动刷新
上节我们说到, HttpHandler
是比 WebHandler
更加底层的一个 API,也就是说很可能是由 HttpHandler 来调用 WebHandler (请求由下往上),但是HttpHandler
的实现类HttpWebHandlerAdapter持有一个WebHandher
对象,通过分析得到持有的WebHandher
具体实现类是ExceptionHandlingWebHandler,那么是怎么调用到DispatcherHandler中的?
HttpWebHandlerAdapter的handle方法
@Override
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
if (this.forwardedHeaderTransformer != null) {
try {
request = this.forwardedHeaderTransformer.apply(request);
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to apply forwarded headers to " + formatRequest(request), ex);
}
response.setStatusCode(HttpStatus.BAD_REQUEST);
return response.setComplete();
}
}
//ServerWebExchange是一个HTTP请求-响应交互的契约。提供对HTTP请求和响应的访问,并公开额外的服务器端处理相关属性和特性,如请求属性。其实,ServerWebExchange命名为服务网络交换器,存放着重要的请求-响应属性、请求实例和响应实例等等,有点像Context的角色。具体实现是DefaultServerWebExchange
ServerWebExchange exchange = createExchange(request, response);
LogFormatUtils.traceDebug(logger, traceOn ->
exchange.getLogPrefix() + formatRequest(exchange.getRequest()) +
(traceOn ? ", headers=" + formatHeaders(exchange.getRequest().getHeaders()) : ""));
//getDelegate()返回的是ExceptionHandlingWebHandler
return getDelegate().handle(exchange)
.doOnSuccess(aVoid -> logResponse(exchange))
.onErrorResume(ex -> handleUnresolvedError(exchange, ex))
.then(Mono.defer(response::setComplete));
}
ExceptionHandlingWebHandler
类的handle方法会调用父类WebHandlerDecorator的handle方法
WebHandlerDecorator.java
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
//前面说过,ExceptionHandlingWebHandler中的delegate保存的是FilteringWebHandler
return this.delegate.handle(exchange);
}
然后会调用到FilteringWebHandler的handle方法
FilteringWebHandler.java
public FilteringWebHandler(WebHandler handler, List<WebFilter> filters) {
//此时传过来的handler就是DispatcherHandler
super(handler);
//初始化的时候会将DefaultWebFilterChain中的handler属性赋值为DispatcherHandler
this.chain = new DefaultWebFilterChain(handler, filters);
}
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
//调用DefaultWebFilterChain中的filter方法
return this.chain.filter(exchange);
}
@Override
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]");
}
通过调试可知,当存在后续filter时,会继续调用filter方法,否则直接调用this.handler.handle方法
此时的this.handler正是DispatcherHandler
public class DefaultWebFilterChain implements WebFilterChain {
private final List<WebFilter> allFilters;
其中的allFilters属性就是之前说过注入HttpWebHandlerAdapter
的时候传入进来的
HttpHandlerAutoConfiguration.java
@Bean
public HttpHandler httpHandler(ObjectProvider<WebFluxProperties> propsProvider) {
//applicationContext方法
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;
}
public static WebHttpHandlerBuilder applicationContext(ApplicationContext context) {
WebHttpHandlerBuilder builder = new WebHttpHandlerBuilder(
context.getBean(WEB_HANDLER_BEAN_NAME, WebHandler.class), context);
//获取所有的WebFilter类型的bean,默认只有WeightCalculatorWebFilter
List<WebFilter> webFilters = context
.getBeanProvider(WebFilter.class)
.orderedStream()
.collect(Collectors.toList());
builder.filters(filters -> filters.addAll(webFilters));
List<WebExceptionHandler> exceptionHandlers = context
.getBeanProvider(WebExceptionHandler.class)
.orderedStream()
.collect(Collectors.toList());
builder.exceptionHandlers(handlers -> handlers.addAll(exceptionHandlers));
context.getBeanProvider(HttpHandlerDecoratorFactory.class)
.orderedStream()
.forEach(builder::httpHandlerDecorator);
······
return builder;
}