在spring cloud gateway中,有两种形式的gatewayFilter,一种是直接实现Global接口的bean,还有一种就是GatewayFilterFactory。这些类在spring-cloud-gateway的core包中的org.springframework.cloud.gateway.filter.factory路径下。
一,初始化
在创建DiscoveryLocatorProperties的时候,创建了一个相关的filter。
@Bean
public DiscoveryLocatorProperties discoveryLocatorProperties() {
DiscoveryLocatorProperties properties = new DiscoveryLocatorProperties();
properties.setPredicates(initPredicates());
properties.setFilters(initFilters());
return properties;
}
public static List<FilterDefinition> initFilters() {
ArrayList<FilterDefinition> definitions = new ArrayList<>();
// add a filter that removes /serviceId by default
FilterDefinition filter = new FilterDefinition();
filter.setName(normalizeFilterFactoryName(RewritePathGatewayFilterFactory.class));
String regex = "'/' + serviceId + '/(?<remaining>.*)'";
String replacement = "'/${remaining}'";
filter.addArg(REGEXP_KEY, regex);
filter.addArg(REPLACEMENT_KEY, replacement);
definitions.add(filter);
return definitions;
}
是用的RewritePathGatewayFilterFactory,我们看下对应的Factory中的内容。
二、RewritePathGatewayFilterFactory
此类中有一个apply方法
@Override
public GatewayFilter apply(Config config) {
String replacement = config.replacement.replace("$\\", "$");
return (exchange, chain) -> {
ServerHttpRequest req = exchange.getRequest();
addOriginalRequestUrl(exchange, req.getURI());
String path = req.getURI().getRawPath();
String newPath = path.replaceAll(config.regexp, replacement);
ServerHttpRequest request = req.mutate()
.path(newPath)
.build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());
return chain.filter(exchange.mutate().request(request).build());
};
}
可以看到其返回了一个GatewayFilter类型,这个里面一个操作,就是换掉serviceId。
这种返回的Filter属于内部类。会与GlobalFilter在一个调用链上执行。
三、各种FilterFactory
在文章开始的包中,有许多的GatewayFilterFactory,在此不一一介绍,有兴趣的可以去包中查看。
四、后续
spring cloud gateway中还有一些接口调用,管理页面的功能,以下文章供分享。
Spring Cloud Gateway网关管理:http://www.iocoder.cn/Spring-Cloud-Gateway/manager-http-api/