Параметр Autowired в качестве параметра объявления компонента

#spring #kotlin #spring-cloud #spring-cloud-config #spring-cloud-gateway

#spring #kotlin #spring-облако #spring-cloud-config #spring-cloud-gateway

Вопрос:

У меня есть

 @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?

Комментарии:

1. Разве это не должно быть автоматическим (по крайней мере, раньше). Вы должны указать маршрут к службе (имя), и он (во время выполнения) будет использовать это имя для преобразования в хост / URL для пересылки.

2. Я хочу, чтобы этот uri был динамическим

3. Я знаю, что вы хотите, но если вы укажете имя службы, URL-адрес будет просматриваться при необходимости, следовательно, динамический.

4. Вы имеете в виду поместить имя службы вместо локального хоста? Не могли бы вы опубликовать пример с кодом?

Ответ №1:

Попробуйте так:

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

Комментарии:

1. Входящий запрос имеет тело параметров запроса. Как бы я их учитывал? Мне не только нужно их захватывать и пересылать, но и мой discoveryService принимает в качестве параметра один из атрибутов параметра запроса, поэтому Id должен иметь возможность выполнять service(requestParamId)

2. Что вы хотите сделать с вашим discoveryService? Чтобы изменить uri пересылки? Или добавить параметр в запрос? Или просто сделать что-то в цепочке запросов?

3. Чтобы изменить uri пересылки

4. Для этого потребуется использовать пользовательскую реализацию spring cloud loadbalancer с использованием подсказок

5. @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 (он также должен быть объявлен как a @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"))

// ...