Можно ли автоматически связать универсальный тип с другим универсальным типом в конструкторе? У меня сейчас такая структура:
@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 для каждого из различных универсальных типов?




Учитывая, как работает стирание типов, оба этих компонента могут быть внедрены просто потому, что Ява примет их оба как допустимые аргументы для конструктора.
Если вы хотите четко указать, что вводится, используйте @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-компонент вам нужен, вы можете пересмотреть добавление здесь дженериков. Во-первых, есть нишевые причины для этого, и поток внедрения зависимостей по-прежнему полностью предсказуем, даже если вы не контролируете жизненный цикл объектов.
Я редко видел выгоду от использования общего компонент. Я видел много-много преимуществ от того, что у компонента есть общие методы, но сам компонент? Не продано. Это привело к таким болевым точкам, когда вы спотыкаетесь на Java-изме.
Хорошо, но если мне иногда нужен ServiceA<Int>, а иногда ServiceA<Long>, мне нужно создать подклассы, такие как ServiceAInt extends ServiceA<Int> и ServiceALong extends ServiceA<Long>, верно? Или что вы имели в виду, говоря о пересмотре использования дженериков?