我找到了处理谓词组合的方法:
RouteDefinitionRouteLocator.java: combinePredicates
:
private AsyncPredicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) {
List<PredicateDefinition> predicates = routeDefinition.getPredicates();
AsyncPredicate<ServerWebExchange> predicate = lookup(routeDefinition, predicates.get(0));
for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) {
AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
predicate = predicate.and(found);
}
return predicate;
}
由于它是一个私有方法,为了用执行谓词的逻辑分离(“OR-ing”)的Path
谓词组合逻辑覆盖这个逻辑,扩展类RouteDefinitionRouteLocator
必须重新定义所有导致最终调用combinePredicates
(这不是最灵活的路线)。但是,我能够通过重新实现这样的方法来实现所需的功能:
private AsyncPredicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) {
//filter out "Path" predicates and place in separate list
List<PredicateDefinition> predicates = routeDefinition.getPredicates();
List<PredicateDefinition> pathPredicates = new ArrayList();
for(PredicateDefinition predicate : predicates){
if (PATH_PREDICATE_NAME.equals(predicate.getName())) {
pathPredicates.add(predicate);
}
}
predicates.removeAll(pathPredicates);
//create an uber predicate out of the "Path" predicates by combining them w/ `or`
AsyncPredicate<ServerWebExchange> pathPredicate = null;
if(pathPredicates.size()>0){
pathPredicate = lookup(routeDefinition, pathPredicates.get(0));
for (PredicateDefinition andPredicate : pathPredicates.subList(1, pathPredicates.size())) {
AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
pathPredicate = pathPredicate.or(found);
}
}
//"AND" together the uber path predicate and the rest of the predicates for the route
AsyncPredicate<ServerWebExchange> predicate;
List<PredicateDefinition> predicateSubList;
if(pathPredicate != null) {
predicate = pathPredicate;
predicateSubList = predicates;
} else {
predicate = lookup(routeDefinition, predicates.get(0));
predicateSubList = predicates.subList(1, predicates.size());
}
for (PredicateDefinition andPredicate : predicateSubList) {
AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
predicate = predicate.and(found);
}
return predicate;
}
然后,用这个新类覆盖声明的routeDefinitionRouteLocator
RouteLocator
@Bean
配置GatewayAutoConfiguration.java
可以使用新的逻辑。