Spring autowire - единственная реализация без определения bean-компонента - PullRequest
0 голосов
/ 26 мая 2020

У меня есть следующий случай:

@Service
interface OrderingService {

}

public class DefaultOrderingService implements OrderingService {

}

@RestController
public class DefaultOrderingRestController {
    private final OrderingService orderingService;
    public DefaultOrderingRestController(OrderingService orderingService) {
        this.orderingService = orderingService;
    }
}

, и я хотел бы, чтобы Spring автоматически подключала единственную реализацию к интерфейсу путем сканирования кода. Возможно ли это?

Другими словами, в настоящее время существует 2 решения этой проблемы, и я спрашиваю, есть ли третье:

  1. Переместите объявление @Service из интерфейса OrderingService к реализации DefaultOrderingService
  2. В Конфигурации определите специфицированный c Bean следующим образом:
 @Configuration 
 public class DefaultConfig {
      @Bean
      public OrderingService orderingService() {
          return new DefaultOrderingService();
      }
 }

ВОПРОС: Возможно ли автоматическое создание Spring сканирование (тогда Spring находит только одну реализацию OrderingService) и autowire? Если да, то как это сделать? Если нет, то почему это не рекомендуется?

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Я не знаю, возможно это или нет, но у меня есть другой подход, который может помочь:

Добавить файл конфигурации для хранения типа вашего bean-компонента, скажем, есть две реализации OrderingService один - FAKE и DEFAULT, чтобы он был только во время выполнения, вы должны объявить оба bean-компонента в контексте проекта, как показано ниже:

@Bean
OrderingService fakeOrderingService() {
  return new FakeOrderingService();
}

@Bean
OrderingService defaultOrderingService() {
  return new DefaultOrderingService();
}

Если вам нужен один из них, у вас есть чтобы добавить ConditionalOnProperty, как показано ниже:

@Bean
@ConditionalOnProperty("app.config.type", havingValue = "FAKE")
OrderingService fakeOrderingService()..

@Bean
@ConditionalOnProperty("app.config.type", havingValue = "DEFAULT", matchIfMissing = true)
OrderingService defaultOrderingService()...

matchIfMissing = true, что поможет, если конфигурация не добавлена ​​в вашей среде, поэтому Spring будет автоматически подключать defaultOrderingService в случае отсутствия свойства или если значение свойства равно DEFAULT, и fakeOrderingService, если значение свойства FAKE

Надеюсь, это поможет

0 голосов
/ 26 мая 2020

Проблема с вашим третьим решением в том, что оно зависит от реализации интерфейса. Если соответствующая реализация не найдена, spring выдаст ошибку. Так что я полагаю, что это определенно плохая практика. Также не наследуется аннотация spring @service. Однако, если вы все еще хотите найти альтернативное решение. Вы можете предпочесть определить отдельные компоненты для каждой реализации и использовать квалификатор для получения компонента из контекста приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...