升级spring-cloud-gateway到4.1.0的过程中遇到的问题的以及对应解决方案
· 2 min read
此文记录了升级spring-cloud-gateway到4.1.0的过程中遇到的问题以及对应的解决方案.
spring.cloud.gateway.routes
中定义的转发规则失效, 提示404 NOT_FOUND "No static resource xxx."
问题原因
这个问题的原因是项目中的类继承了org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping
但是新版本不兼容导致的.
在新版本中RoutePredicateHandlerMapping
的@Bean
定义增加了@ConditionalOnMissingBean
.
定义位于
org.springframework.cloud.gateway.config.GatewayAutoConfiguration
中.
RoutePredicateHandlerMapping
是HandlerMapping
的实现, 对于注册到容器中的HandlerMapping
,spring-mvc-reactive
会自动调用这些类的方法来尝试处理请求.
由于多出了@ConditionalOnMissingBean
这会导致框架内置的和自定义的RoutePredicateHandlerMapping
出现互斥的问题, 即只会被注册一次.
但是由于重写的方法只实现了部分自定义的转发规则, 从而导致spring.cloud.gateway.routes
中定义的转发规则失效.
3.0.2中的Bean定义如下:
@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties, environment);
}
3.4.0中的Bean定义如下:
@Bean
@ConditionalOnMissingBean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties, environment);
}
解决方案
修改继承类重写的protected Mono<Route> lookupRoute(ServerWebExchange exchange)
方法的实现, 先调用父类的方法, 如果父类方法返回为空,
则执行自定义的转发规则以确保spring.cloud.gateway.routes
中定义的转发规则生效.
@Override
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return super.lookupRoute(exchange).switchIfEmpty(Mono.defer(() -> {
// 此处为自定义的转发规则
}
));
}