You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Gateway MVC结合Eureka服务发现及路由列表获取咨询

解决方案:Spring Cloud Gateway MVC 集成 Eureka 及路由列表获取

1. Gateway MVC 与 Eureka DiscoveryClient 集成配置

依赖配置

先引入 Gateway MVC 和 Eureka Client 核心依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway-mvc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

应用配置

在 application.yml 中配置 Eureka 连接参数:

spring:
  application:
    name: gateway-mvc-service
eureka:
  client:
    service-url:
      defaultZone: http://your-eureka-server:8761/eureka/
    fetch-registry: true
    register-with-eureka: true

自动生成Eureka服务路由

创建配置类,基于 DiscoveryClient 为所有注册服务自动生成路由规则:

import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.gateway.mvc.handler.HandlerFunctions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.function.RequestPredicates;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;

@Configuration
public class EurekaRouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> eurekaDiscoveryRoutes(DiscoveryClient discoveryClient) {
        RouterFunction<ServerResponse> router = RouterFunction.route();
        
        // 遍历Eureka中所有服务,生成路由:/服务ID/** 转发到对应服务
        for (String serviceId : discoveryClient.getServices()) {
            router = router.andRoute(
                RequestPredicates.path("/" + serviceId + "/**"),
                HandlerFunctions.http()
                    .uri("lb://" + serviceId + "/{path}")
                    .build()
            );
        }
        return router;
    }
}

2. 自定义过滤器中获取路由列表

注意:RouteLocator 是 WebFlux 版本 Gateway 的组件,不适用于 MVC 场景。可以通过 RoutePredicateHandlerMapping 获取所有注册的路由信息:

修改过滤器配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;
import org.springframework.web.servlet.handler.RoutePredicateHandlerMapping;

@Configuration
public class CustomRouteFilterConfiguration {

    private final RoutePredicateHandlerMapping routeMapping;

    // 构造注入路由映射器
    public CustomRouteFilterConfiguration(RoutePredicateHandlerMapping routeMapping) {
        this.routeMapping = routeMapping;
    }

    @Bean
    public RouterFunction<ServerResponse> tokenRelay() {
        return RouterFunction.route("access_control_route")
            .route(RequestPredicates.path("/**"), HandlerFunctions.http())
            .filter(RoutesFilterFunctions.filterOnRoutes(jHipsterProperties, routeMapping))
            .build();
    }
}

修改过滤器实现类

import org.springframework.cloud.gateway.mvc.annotation.Shortcut;
import org.springframework.web.servlet.function.HandlerFilterFunction;
import org.springframework.web.servlet.function.ServerRequest;
import org.springframework.web.servlet.function.ServerResponse;
import org.springframework.web.servlet.handler.RoutePredicateHandlerMapping;

public class RoutesFilterFunctions {

    @Shortcut
    public static HandlerFilterFunction<ServerResponse, ServerResponse> filterOnRoutes(JHipsterProperties jHipsterProperties, RoutePredicateHandlerMapping routeMapping) {
        return (request, next) -> {
            boolean isAuthorizedRequest = false;
            
            // 遍历所有注册的路由规则,predicate为路由匹配条件,handlerMethod为对应处理逻辑
            routeMapping.getHandlerMethods().forEach((predicate, handlerMethod) -> {
                // 自定义路由校验逻辑,例如判断请求路径是否匹配路由规则
                // do something here
            });
            
            return next.handle(request);
        };
    }
}

备选方案:自定义路由注册表

如果需要更灵活的路由信息管理,可以手动维护路由注册表:

// 自定义路由注册表组件
@Component
public class RouteRegistry {
    private final List<RouteMeta> routes = new CopyOnWriteArrayList<>();
    
    public void addRoute(RouteMeta route) {
        routes.add(route);
    }
    
    public List<RouteMeta> getRoutes() {
        return routes;
    }
}

// 在EurekaRouteConfiguration中注册路由时同步存入注册表
router = router.andRoute(..., ...);
routeRegistry.addRoute(new RouteMeta(serviceId, "/"+serviceId+"/**"));

// 过滤器中直接读取注册表
public static HandlerFilterFunction<ServerResponse, ServerResponse> filterOnRoutes(RouteRegistry routeRegistry) {
    return (request, next) -> {
        for(RouteMeta route : routeRegistry.getRoutes()) {
            // 自定义逻辑
        }
        return next.handle(request);
    };
}

内容的提问来源于stack exchange,提问作者j-mk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 21:05:56