Разрешение конфликта Spring с помощью @Autowired и @Qualifier

#java #spring-mvc #annotations

#java #spring-mvc #аннотации

Вопрос:

У меня есть интерфейс

 public interface ParentService{}
  

И два класса реализации

 @Service("child1service")    
public class Child1 implements ParentService{}

@Service("child2service")
public class Child2 implements ParentService{}
  

Теперь мой контроллер

 public class ServeChild1Controller extendds AbstractController{

 @Autowired
 public ServeChild1Controller(@Qualifier("child1service") ParentService child1service){
 super(child1service)
  } 
  

Аналогично существует ServeChild2Controller ..

Итак, когда я запускаю, я получаю следующую ошибку

Ошибка для ServeChild1Controller: нет уникального компонента типа [com.service.Определен ParentService]: ожидаемый единственный соответствующий компонент, но найдено 2 дочерних 1service, child2service

Я пытаюсь больше узнать об этих аннотациях, но не могу их разрешить.. Любые указатели помогут, спасибо

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

1. Какую версию Spring вы используете?

2. я использую версию spring 3.0.5

Ответ №1:

Чтобы использовать конкретный экземпляр, вам необходимо предоставить аннотировать службу с помощью @Qualifier(id) и в конструкторе снова указать параметр с помощью @Qualifier, следующим образом:

 @Service("child1service")
@Qualifier("child1service")
public class Child1 implements ParentService{}

@Service("child2service")
@Qualifier("child2service")
public class Child2 implements ParentService{}
  

И вы создаете:

 public class ServeChild1Controller extendds AbstractController{

    @Autowired
    public ServeChild1Controller(@Qualifier("child1service") ParentService child1service){
        super(child1service)
    }

}
  

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

1. требуется ли указывать идентификатор как с аннотацией Service, так и с аннотацией Qualifier?

2. @DaxJoshi: вы можете определить его только на @Qualifier

3. Вы можете просто определить как @Service(«child1service»)

Ответ №2:

С Spring (beans) 4.3 он работает точно так, как вы написали в своем вопросе.

Я могу привести вам пример с группированием реализации, с которым я столкнулся недавно. Spring может автоматически подключаться на основе различий между типом и квалификатором. Недостаточно использовать имена служб, поскольку они должны быть уникальными, чтобы в итоге возник конфликт типов.

Пример:

 public interface ServiceA {}
public interface ServiceB {}

@Qualifier("mockedA")    
@Service
public class MockedA implements ServiceA {}

@Qualifier("realA")
@Service
public class RealA implements ServiceA {}

@Qualifier("mockedB")    
@Service
public class MockedB implements ServiceB {}

@Qualifier("realB")
@Service
public class RealB implements ServiceB {}

@Autowired
public ABController (
    @Qualifier("mockedA") ServiceA mockedA,
    @Qualifier("realA") ServiceA realA,
    @Qualifier("mockedB") ServiceB mockedB,
    @Qualifier("realB") ServiceB realB) {
} 
  

Ответ №3:

Я думаю, что аннотацию @Qualifier, возможно, потребуется предоставить на том же уровне, что и аннотацию @Autowired .