目录
前言:
我其实就是想弄明白SpringCloud Gateway 中 Filter链表的构建原理和注入到Bean的时机,如果动态注入过滤器为Bean什么样的时机注入在默认情况下会生效,如果无法生效是因为什么原因,通过重写哪些方法类可以迫使生效。
过滤器和过滤器链
Spring Cloud Gateway根据作用范围划分为GatewayFilter和GlobalFilter。
- GatewayFilter:需要通过spring.cloud.routes.filters配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上
- GlobalFilter:全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器,它为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,系统初始化时加载,并作用在每个路由上。
一些关键的类和接口
OrderGatewayFilter类实现了GatewayFilter和Ordered接口,将目标过滤器包装成可排序的对象类型,是目标过滤器的包装类。
GatewayFilterAdapter类实现了GatewayFilter,主要是将GlobalFilter过滤器包装成GatewayFilter类型的对应。是GlobalFilter过滤器的包装类。
FilteringWebHandler将GlobalFilter转化成GatewayFilter并生成DefaultGatewayFilterChain。
GatewayFilterChain网关过滤链表-接口
DefaultGatewayFilterChain 上面的实现类
网关过滤的链表,用于过滤器的链式调用。过滤器链表接口的默认实现。
源码分析
GatewayAutoConfiguration
配置类,将FilteringWebHandler注册为Bean
……
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore({
HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class })
@AutoConfigureAfter({
GatewayReactiveLoadBalancerClientAutoConfiguration.class,
GatewayClassPathWarningAutoConfiguration.class })
@ConditionalOnClass(DispatcherHandler.class)
//这个配置类基本上加载了大部分Gateway的Bean
public class GatewayAutoConfiguration {
//上下文会扫描到这个配置类,然后扫描方法进行Bean的注入
//各种乱七八糟的Handler都是通过这个配置类注入为Bean的
……
//根据获取配置类的方法扫描到这里,进行FilteringWebHandler的注入
//在注入FilteringWebHandler之前,所有的过滤器已经注入过了
/**或者说纯@Configuration的注入优先级没有那么高,就是不会是很早注入的
/*没有哪种继承什么ContextAware的、BeanPostProcessor的、@Component的
/*那样会先加载。
/*所以说所有的过滤器已经在此之前实例化过了,
/*这里就会将所有的GlobalFilter类型的Bean全部作为依赖注入进来
/* 如果有过滤器在这个之后加入,那应该就不会生效了 )
/* 因为那个过滤器链是final的,,,,,,后面会细说
**/
@Bean
public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) {
return new FilteringWebHandler(globalFilters);
}
@Bean
public GlobalCorsProperties globalCorsProperties() {
return new GlobalCorsProperties();
}
//路由处理 这里依赖一个webHandler,这个应该是路由下的过滤器
@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties, environment);
}
……
FilteringWebHandler
- org.springframework.cloud.gateway.handler.FilteringWebHandler
package org.springframework.cloud.gateway.handler;
……
import org.springframework.web.server.WebHandler;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
/**
* WebHandler that delegates to a chain of {@link GlobalFilter} instances and
* {@link GatewayFilterFactory} instances then to the target {@link WebHandler}.
*
* @author Rossen Stoyanchev
* @author Spencer Gibb
* @since 0.1
*/
public class FilteringWebHandler implements WebHandler {
protected static final Log logger = LogFactory.getLog(FilteringWebHandler.class);
//全局过滤器链 final类型 初始定义之后就不能再改动了 好处是线程安全
private final List<GatewayFilter> globalFilters;
//通过配置类获取的所有GlobalFilter,成为一个final的链表
public FilteringWebHandler(List<GlobalFilter> globalFilters) {
this.globalFilters = loadFilters(globalFilters);
}
//将GlobaFilter转换为GatewayFilter串成链表
private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
return filters.stream().map(filter -> {
GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
if (filter instanceof Ordered) {
int order = ((Ordered) filter).getOrder();
return new OrderedGatewayFilter(gatewayFilter, order);
}
return gatewayFilter;
}).collect(Collectors.toList());
}
//路由处理应该要走这个handle方法
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
//获得route
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?
//根据order进行排序
AnnotationAwareOrderComparator.sort(combined);
if (logger.isDebugEnabled()) {
logger.debug("Sorted gatewayFilterFactories: " + combined);
}
//返回默认的网关过滤链
return new DefaultGatewayFilterChain(combined).filter