SpringCloud网关过滤器GatewayFilterFactory找不到

1、目标

本篇文章的主要目标是找到网关过滤器找不到的原因,并进行源码跟踪

2、报错现象

设置网关过滤器,继承AbstractGatewayFilterFactory,重写apply方法

@Component
@Log4j2
public class VerifyGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            log.info("request: " + request);
            log.info("网关过滤器VerifyGatewayFilter");
            return chain.filter(exchange);
        };
    }
}

在Nacos的配置文件设置demo04-payment-service服务的路由转发

- id: demo04-payment
  uri: lb://demo04-payment-service
  predicates:
    - Path=/paymentPath/**
  filters:
    - VerifyGatewayFilterFactory
    - RewritePath=/paymentPath(?<segment>/?.*), $\{segment}

启动服务后会抛出异常:

java.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name VerifyGatewayFilterFactory
	at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.loadGatewayFilters(RouteDefinitionRouteLocator.java:130) ~[spring-cloud-gateway-server-3.0.3.jar:3.0.3]
	Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Assembly trace from producer [reactor.core.publisher.FluxMapFuseable] :
	reactor.core.publisher.Flux.map(Flux.java:6091)
	org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.getRoutes(RouteDefinitionRouteLocator.java:95)
Error has been observed at the following site(s):
	|_               Flux.map ⇢ at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.getRoutes(RouteDefinitionRouteLocator.java:95)
	|_               Flux.map ⇢ at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.getRoutes(RouteDefinitionRouteLocator.java:107)
	|_ Flux.flatMapSequential ⇢ at org.springframework.cloud.gateway.route.CompositeRouteLocator.getRoutes(CompositeRouteLocator.java:34)
	|_              Flux.sort ⇢ at org.springframework.cloud.gateway.route.CachingRouteLocator.fetch(CachingRouteLocator.java:61)
	|_              Flux.sort ⇢ at org.springframework.cloud.gateway.route.CachingRouteLocator.fetch(CachingRouteLocator.java:61)
	|_              Flux.sort ⇢ at org.springframework.cloud.gateway.route.CachingRouteLocator.fetch(CachingRouteLocator.java:61)
	|_           Flux.collect ⇢ at org.springframework.cloud.gateway.route.CachingRouteLocator.onApplicationEvent(CachingRouteLocator.java:81)
Stack trace:
		at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.loadGatewayFilters(RouteDefinitionRouteLocator.java:130) ~[spring-cloud-gateway-server-3.0.3.jar:3.0.3]
		at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.getFilters(RouteDefinitionRouteLocator.java:176) ~[spring-cloud-gateway-server-3.0.3.jar:3.0.3]
		at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.convertToRoute(RouteDefinitionRouteLocator.java:117) ~[spring-cloud-gateway-server-3.0.3.jar:3.0.3]

3、源码跟踪

根据报错信息可以跟踪网关过滤器的源码

进入RouteDefinitionRouteLocator构造器

在这里插入图片描述

初始化RouteDefinitionRouteLocator对象会遍历gatewayFilterFactories这个list集合,然后将GatewayFilterFactory对象的name作为map的key,将GatewayFilterFactory对象作为map的value,存放到map中

进入factory的name()方法

在这里插入图片描述

该方法会将容器中VerifyGatewayFilterFactory网关过滤器对象的类名去除GatewayFilterFactory的类名,因此map的key会保存Verify作为网关过滤器的name

这里Class类对象的getSimpleName方法会返回类名

replace("xxx’, “”)会将这个字符串的xxx替换成空,即删除xxx字符串

在这里插入图片描述

该方法会解析Nacos配置文件中的网关路由RouteDefinition对象,其中filters是Nacos配置文件中的网关过滤器的名字VerifyGatewayFilterFactory和RewritePath

然后执行loadGatewayFilters方法

在这里插入图片描述

该方法会从gatewayFilterFactories这个map中根据key=VerifyGatewayFilterFactory得到value是null,因为gatewayFilterFactories这个map保存了Verify这个key,也就是说容器中的map的key是去除GatewayFilterFactory的名字,而Nacos配置文件中设置网关过滤器的名字是VerifyGatewayFilterFactory,因此从map获取不到VerifyGatewayFilterFactory对象就会报错:
Unable to find GatewayFilterFactory with name VerifyGatewayFilterFactory

4、解决办法

在这里插入图片描述

将网关过滤器的名字设置成Verify

在这里插入图片描述

这样就可以找到网关过滤器,启动服务正常

网关配置是

spring:
  cloud:
    gateway:
      routes:
        - id: demo04-order
          uri: lb://demo04-order-service
          predicates:
            - Path=/orderPath/**
          filters:
            - RewritePath=/orderPath(?<segment>/?.*), $\{segment}

        - id: demo04-payment
          uri: lb://demo04-payment-service
          predicates:
            - Path=/paymentPath/**
          filters:
            - Verify
            - RewritePath=/paymentPath(?<segment>/?.*), $\{segment}

执行localhost:8080/paymentPath/payment/m1,测试网关过滤器是否生效

在这里插入图片描述

可以看到访问网关的paymentPath路径会经过网关过滤器VerifyGatewayFilterFactory,因为网关路由转发paymentPath路径配置了Verify

执行localhost:13087/orderPath/order/f1,不会经过网关过滤器VerifyGatewayFilterFactory,因为网关路由转发orderPath路径没有配置Verify

  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Gateway是基于Spring Framework 5,Spring Boot 2和Project Reactor等技术构建的网关,它提供了一些强大的路由功能,可以用于构建微服务应用程序。 Spring Cloud Gateway中的过滤器(Filter)是一个非常重要的组件,可以用来对进入网关的请求进行处理,例如身份验证、日志记录、限流等。Spring Cloud Gateway支持两种类型的过滤器:全局过滤器和路由过滤器。其中全局过滤器将会应用到所有的路由上,而路由过滤器只会应用到指定的路由上。 下面是Spring Cloud Gateway自定义过滤器的流程: 1. 创建一个类,实现org.springframework.cloud.gateway.filter.GlobalFilter接口或者org.springframework.cloud.gateway.filter.GatewayFilter接口。 2. 实现接口中的filter方法,该方法接收一个ServerWebExchange对象和一个GatewayFilterChain对象作为参数。ServerWebExchange对象表示当前请求和响应的上下文信息,GatewayFilterChain对象表示当前过滤器链。 3. 在filter方法中编写自己的业务逻辑,例如身份验证、日志记录、限流等。 4. 如果实现的是全局过滤器,则需要在应用启动类中注册该过滤器。可以通过@Bean注解将该过滤器注入到Spring容器中。 5. 如果实现的是路由过滤器,则需要在定义路由的配置中注册该过滤器。可以通过GatewayFilterSpec类的filter方法将该过滤器添加到路由的过滤器链中。 6. 启动应用程序,测试自定义过滤器是否生效。 以上就是Spring Cloud Gateway自定义过滤器的流程,通过自定义过滤器可以实现更加灵活、高效的网关应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值