【问题标题】:Autowired parameter as bean declaration parameter自动装配参数作为 bean 声明参数
【发布时间】:2021-02-11 19:24:09
【问题描述】:

我有

@Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
    return builder.routes()
                  .route(r -> r.path("/employee/**")
                               .uri("http://localhost:8081/")
                               .id("employeeModule"))
                  .build()

但是我想要一个动态派生值而不是http:://localhost:8081/,例如:

@Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder builder,
                                  @Autowired val discoveryService: DiscoveryService) {
    return builder.routes()
                  .route(r -> r.path("/employee/**")
                               .uri(discoveryService.getHost())
                               .id("employeeModule"))

这可能吗?我应该如何更改语法以自动装配 DiscoveryService?

【问题讨论】:

  • 不应该是自动的(至少它曾经是)。您应该放置一个到服务(名称)的路由,它将(在运行时)使用该名称解析为要转发到的主机/url。
  • 我希望这个 uri 是动态的
  • 我知道您想要什么,但如果您指定服务名称,则会在需要时查找 URL,因此是动态的。
  • 您的意思是放置服务的名称而不是本地主机?能否请您发布一个带有代码的示例?

标签: spring kotlin spring-cloud spring-cloud-config spring-cloud-gateway


【解决方案1】:

试试这样:

    RouteLocatorBuilder.Builder routes = builder.routes();
    discoveryClient.getServices().forEach(service->routes.route(r -> r.path("/"+service+"/**")
            .uri("lb://"+service).id(service)));
    return routes.build();

【讨论】:

  • 传入的请求有一个请求参数的主体。我将如何解释他们?我不仅需要捕获和转发它们,而且我的 discoveryService 将请求参数属性之一作为参数,因此 Id 需要能够执行 service(requestParamId)
  • 你想用你的discoveryService做什么?改变转发uri?或者给请求添加一个参数?或者只是在请求链中做点什么?
  • 更改转发uri
  • 这需要使用自定义的 spring 云负载均衡器实现,使用提示
  • @C96 为什么要更改转发 uri?选择同一服务的不同版本/实例?如果是这样,就按照 spencergibb 说的做。
【解决方案2】:

你可以这样做:

@Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder builder,
                                  // note the absence of val
                                  @Autowired discoveryService: DiscoveryService) {
    return builder.routes()
                  .route(r -> r.path("/employee/**")
                               .uri(discoveryService.getHost())
                               .id("employeeModule"))

这将自动装配DiscoveryService(它也必须被声明为@Bean或者你可以直接调用声明DiscoveryService的方法,因为Spring会增强该方法CGLIB 所以它只会创建一次DiscoveryService

@Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
    return builder.routes()
                  .route(r -> r.path("/employee/**")
                               // note the discoveryService() function call
                               .uri(discoveryService().getHost())
                               .id("employeeModule"))

// ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多