赞
踩
对源码做简单修改,比如,Path 匹配 /mock/**
则对路由查找结果进行缓存(注意这里缓存策略和方式仅仅是举例,根据实际需求情况来做)
public static final String MOCK_PATCH = "/mock/**";
private Map<String, Route> hashCache = new ConcurrentHashMap<>(1024);
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
String path = exchange.getRequest().getPath().subPath(0).value();
//符合Path规则,优先从缓存Map获取,时间复杂度近似于O(1)
if (pathMatcher.match(MOCK_PATCH, path)) {
return Mono.justOrEmpty(hashCache.get(path))
.switchIfEmpty(getRouteMono(exchange, path));
}
return getRouteMono(exchange, path);
}
private Mono<Route> getRouteMono(ServerWebExchange exchange, String path) {
return this.routeLocator.getRoutes()
//... 略过
.map(route -> {
if (logger.isDebugEnabled()) {
logger.debug("Route matched: " + route.getId());
}
validateRoute(route, exchange);
//符合Path规则,缓存路由
if (pathMatcher.match(MOCK_PATCH, path)) {
hashCache.put(path, route);
}
return route;
});
}
继续查阅源码,找到RoutePredicateHandlerMapping 是如何装配的。在GatewayAutoConfiguration 中实现了 SpringCloud Gateway 内部组件的自动装配,RoutePredicateHandlerMapping 也在其中,代码入下:
@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties, environment);
}
很遗憾,官方没有给这个自动装配添加条件,我们无法自行装配替代默认装配。
我们只能采取以下步骤:
在 Springboot 启动类上增加排除 GatewayAutoConfiguration 的自动装配配置;
继承 GatewayAutoConfiguration 并完全拷贝其装配条件;
覆盖父类 routePredicateHandlerMapping
方法,给装配添加条件;
继承RoutePredicateHandlerMapping ,覆盖其 lookupRoute
方法,符合一定条件的请求,优先从缓存中查找路由。
@SpringBootApplication(exclude = GatewayConfiguration.class)
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore({HttpHa
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。