1. 请求流程
前面分析过Spring Cloud Gateway由三个组件来完成请求的分发和增强,predicate判定走哪个路由route,然后经过各个过滤器的处理,大致的类图流程如下:
2. 源码分析
我们从源码中来看看上面三个类是如何加载的,基于Spring Boot的加载套路,我们可以从spring-cloud-gateway-server组件中找到META-INF/spring.factories文件,从配置的类里找出答案。进入GatewayAutoConfiguration类,可以发现这几个类的加载方式。
RoutePredicateHandlerMapping的装配
RoutePredicateHandlerMapping作为路由的判定器,会把FilteringWebHandler和routeLocator注入进来,这样的设计挺合理的,选择路由和调用过滤器的逻辑就可以在一个类中完成。
@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(
FilteringWebHandler webHandler, RouteLocator routeLocator,
GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator,
globalCorsProperties, environment);
}
RouteLocator的装配
RouteLocator的装配依赖RouteDefinitionLocator,可以看到RouteDefinitionLocator和RouteLocator的装配用了比较巧妙的方式,在方法参数里直接注入了集合。另外用了@Primary注解来告诉容器优先选择自己。
@Bean
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
List<GatewayFilterFactory> gatewayFilters,
List<RoutePredicateFactory> predicates,
RouteDefinitionLocator routeDefinitionLocator,
ConfigurationService configurationService) {
return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates,
gatewayFilters, properties, configurationService);
}
@Bean
@Primary
@ConditionalOnMissingBean(name = "cachedCompositeRouteLocator")
public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
return new CachingRouteLocator(
new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
}
// 这里收集所有的的路由信息,也就是路由表
@Bean
@Primary
public RouteDefinitionLocator routeDefinitionLocator(
List<RouteDefinitionLocator> routeDefinitionLocators) {
return new CompositeRouteDefinitionLocator(
Flux.fromIterable(routeDefinitionLocators));
}
FilteringWebHandler的装配
FilteringWebHandler也是收集了所有的全局过滤器
@Bean
public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) {
return new FilteringWebHandler(globalFilters);
}