spring cloud gateway的核心類DispatcherHandler 這個(gè)類就和springmvc的dispatcherHandler的地位是一樣的婆殿,所有的請求都會經(jīng)過他。他的主要方法是handler
@Override
public Mono handle(ServerWebExchange exchange) {
if (logger.isDebugEnabled()) {
ServerHttpRequest request = exchange.getRequest();
logger.debug("Processing " + request.getMethodValue() +" request for [" + request.getURI() +"]");
}
if (this.handlerMappings ==null) {
return Mono.error(HANDLER_NOT_FOUND_EXCEPTION);
}
return Flux.fromIterable(this.handlerMappings)
.concatMap(mapping -> mapping.getHandler(exchange))
.next()
.switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION))
.flatMap(handler -> invokeHandler(exchange, handler))
.flatMap(result -> handleResult(exchange, result));
}
?關(guān)鍵代碼(二)invokeHandler(exchange, handler)
1.invokeHadler里面調(diào)用了SimpleHandlerAdapter.handle(exchange, handler)
? ??????????????????????????????????????????
private Mono 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));
}
2.SimpleHandlerAdapter.handle(exchange, handler)里面又調(diào)用了gateway包下面的FilteringWebHandler.handle(ServerWebExchange exchange)方法哑了,在這里面獲取了之前放到上下文中的GATEWAY_ROUTE_ATTR,然后獲取filters,給所有的過濾器進(jìn)行排序,然后執(zhí)行這些過濾器
public Mono handle(ServerWebExchange exchange) {
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
List gatewayFilters = route.getFilters();
List combined =new ArrayList<>(this.globalFilters);
combined.addAll(gatewayFilters);
//TODO: needed or cached?
? AnnotationAwareOrderComparator.sort(combined);
logger.debug("Sorted gatewayFilterFactories: "+ combined);
return new DefaultGatewayFilterChain(combined).filter(exchange);
}
3.前面初始化的時(shí)候掂墓,有初始化一個(gè)LoadBalancerClientFilter,在這里執(zhí)行這個(gè)filters鏈的時(shí)候有執(zhí)行這個(gè)filter
@Configuration
@ConditionalOnClass({LoadBalancerClient.class, RibbonAutoConfiguration.class, DispatcherHandler.class})
@AutoConfigureAfter(RibbonAutoConfiguration.class)
public class GatewayLoadBalancerClientAutoConfiguration {
// GlobalFilter beans
? @Bean
? @ConditionalOnBean(LoadBalancerClient.class)
public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
return new LoadBalancerClientFilter(client);
}
}
這個(gè)就是創(chuàng)建了一個(gè)LoadBalancerClientFilter的對象看成,這個(gè)對象中的最主要的方法就是filter()君编,而filter()中最關(guān)鍵代碼就是調(diào)用了RibbonLoadBalancerClient.choose(String serviceId)
final ServiceInstance instance =loadBalancer.choose(url.getHost());
下面就是ribbon的源碼了
public ServiceInstance choose(String serviceId) {
Server server = getServer(serviceId);
if (server ==null) {
return null;
}
return new RibbonServer(serviceId, server, isSecure(server, serviceId),
serverIntrospector(serviceId).getMetadata(server));
}
這些就是spring cloud gateway 關(guān)鍵流程的源碼解析
知識點(diǎn):
這個(gè)在config中有用到單例模式,這個(gè)是單例模式的一種應(yīng)用川慌,一個(gè)config被spring容器管理后吃嘿,默認(rèn)是單例的,所以在自動加載的時(shí)候可以先對該config進(jìn)行配置的set,然后在被spring管理的其他的類中進(jìn)行g(shù)et獲取到