Компонент Autowire Spring, реализующий два интерфейса

#spring #dependency-injection #autowired

#spring #внедрение зависимостей #автоматическое подключение

Вопрос:

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

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

 public interface ServiceA {}

public interface ServiceB {}
  

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

 @RestController
public class ControllerA {

    public ControllerA(ServiceA service) {}

}

@RestController
public class ControllerB {

    public ControllerB(ServiceB service) {}

}
  

Один класс, который реализует обе службы

 @Service
public class ServiceImpl implements ServiceA, ServiceB { }
  

Я получаю NoSuchBeanDefinitionException :

Вызвано: org.springframework.beans.factory.Исключение NoSuchBeanDefinitionException: не найден соответствующий компонент типа [ServiceB] для зависимости [ServiceB]: ожидается по крайней мере 1 компонент, который квалифицируется как кандидат autowire для этой зависимости. Аннотации зависимостей: {}

Я использую Spring Boot версии 1.4.0

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

1. Я не вижу никаких @Service или аналогичных в этих интерфейсах

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

Ответ №1:

Да, это возможно, но важно создать компонент службы типа ServiceImpl , а не как один из интерфейсов службы :

 @Bean
ServiceImpl service() {
    return new Serviceimpl();
}
  

Spring использует отражение объявленного типа компонента, чтобы выяснить, какие интерфейсы он реализует, а какие нет bean.getClass() .

Даже если этот ответ был признан отрицательным, вы можете быть уверены: он работает. Если это не работает для вас @scarba05, ваша проблема должна быть где-то в другом месте…

Ответ №2:

Вы могли бы использовать @Qualifier аннотацию. Он может быть применен вместе @Autowired с или @Inject в точке внедрения, чтобы указать, какой компонент вы хотите внедрить:

 @Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert) {
    this.dessert = dessert;
}
  

Источник: Spring в действии, 4-е издание.

Ответ №3:

Позвольте мне ответить на ваши вопросы один за другим:

  1. Да, вы можете реализовать более одного интерфейса в любом компоненте spring.
  2. Да, вы также можете автоматически подключаться к интерфейсу, как и с помощью конструктора.

Ваш общий код работает нормально, просто проверьте свой класс SpringBootConfiguration Я думаю, вы не сканируете свой пакет услуг, или ваш класс обслуживания отсутствует в дочернем пакете класса SpringBootConfiguration.

Вот почему вы сталкиваетесь:

Исключение NoSuchBeanDefinitionException