Spring вложенная автопроводка общих бросков NoUniqueBeanDefinitionException

Можно ли автоматически связать универсальный тип с другим универсальным типом в конструкторе? У меня сейчас такая структура:

@Service
public class ExampleService {
@Autowired
ServiceA<Integer> servicea;

}

и услуги:

@Component
@Scope(SCOPE_PROTOTYPE)
public class ServiceA<S> {
  private final ServiceB<S,String> dependentServiceB;

  public ServiceA (ServiceB<S,String> dependentServiceB){
     this.dependentServiceB = dependentServiceB;
  }
}

@Configuration
public class ServiceBConfig {
  @Bean
  ServiceB<Integer,String> serviceBwithInt (){
      return new ServiceBImplInt();
  }

  @Bean
  ServiceB<Long,String> serviceBwithLong (){
      return new ServiceBImplLong();
  }

}

Теперь, если я попытаюсь автоматически связать класс ExampleService где-нибудь в другом месте, он выдает исключение NoUniqueBeanDefinitionException, содержащее «Нет доступного квалификационного bean-компонента типа '....ServiceB< ? >': ожидается один соответствующий bean-компонент, но найдено 2: serviceBwithInt, serviceBwithLong".

Возможно ли это решить таким образом, или мне нужно реализовать подклассы ServiceA для каждого из различных универсальных типов?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
170
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Учитывая, как работает стирание типов, оба этих компонента могут быть внедрены просто потому, что Ява примет их оба как допустимые аргументы для конструктора.

Если вы хотите четко указать, что вводится, используйте @Qualifier.

@Component
@Scope(SCOPE_PROTOTYPE)
public class ServiceA<S> {
  private final ServiceB<S,String> dependentServiceB;

  public ServiceA (@Qualifier("serviceBWithInt")ServiceB<S,String> dependentServiceB){
     this.dependentServiceB = dependentServiceB;
  }
}

Если вы не можете явно указать, какой bean-компонент вам нужен, вы можете пересмотреть добавление здесь дженериков. Во-первых, есть нишевые причины для этого, и поток внедрения зависимостей по-прежнему полностью предсказуем, даже если вы не контролируете жизненный цикл объектов.

Хорошо, но если мне иногда нужен ServiceA<Int>, а иногда ServiceA<Long>, мне нужно создать подклассы, такие как ServiceAInt extends ServiceA<Int> и ServiceALong extends ServiceA<Long>, верно? Или что вы имели в виду, говоря о пересмотре использования дженериков?

joz 31.01.2019 18:41

Я редко видел выгоду от использования общего компонент. Я видел много-много преимуществ от того, что у компонента есть общие методы, но сам компонент? Не продано. Это привело к таким болевым точкам, когда вы спотыкаетесь на Java-изме.

Makoto 31.01.2019 18:43

Другие вопросы по теме