Spring Autowire Annotation on Abstract class: уникальный bean-компонент не определен

У меня есть абстрактный класс:

@Component
public abstract class BaseReport {

  public void export() {
   ...
}

И куча классов, которые расширяют его и переопределяют метод export() (или нет).

@Component
public final class Report1 extends BaseReport

@Component
public final class Report2 extends BaseReport

Большинство моих тестов без проблем автоматически подключают конкретные классы, расширяющие BaseReport:

public class Report1Test extends BaseTest {

    @Autowired
    Report1 _report;

public class Report2Test extends BaseTest {

    @Autowired
    Report2 _report;

Это прекрасно работает для автосвязывания всех классов, которые расширяют BaseReport. Но мне также нужно автоматически связать сам абстрактный класс BaseReport, чтобы протестировать метод export().

public class BaseReportTest extends BaseTest {

  @Autowired
  BaseReport _report;

Когда я пытаюсь запустить его, я получаю печально известное:

Уникальный bean-компонент типа BaseReport не определен: ожидается один соответствующий bean-компонент, но найдено 2 [Report1, Report2].

Я пытался использовать @Qualifier, но проблема с @Qualifier заключается в том, что (насколько я понимаю) вы используете его, чтобы сообщить Spring, какой класс — который реализует интерфейс или расширяет абстрактный класс — вы хотите использовать. Но это не мой случай. Я хочу использовать сам абстрактный класс.

Я также пытался использовать @Resource, например:

public class BaseReportTest extends BaseTest {

  @Resource(name = "baseReport")
  BaseReport _report;

Spring говорит мне, что bean-компонента с таким именем не существует. :(

Как я могу это сделать?

Ваше здоровье.


person Robert Bowen    schedule 12.04.2013    source источник


Ответы (1)


Абстрактные классы не могут быть созданы, вам нужно использовать конкретную реализацию. Как и в обычной Java, если вы пытаетесь создать экземпляр абстрактного класса, он говорит вам реализовать абстрактные методы внутри. Когда вы это сделаете, будет создан анонимный класс. Это не создание абстрактного класса, а новый подкласс этого абстрактного класса.

Spring будет искать классы, которые расширяют ваш базовый класс, такие как Report1 и Report2, Spring видит, что у него есть несколько классов, которые соответствуют требованиям, и не знает, какой из них выбрать. таким образом, вы получаете ошибку о том, что существует несколько совпадающих bean-компонентов.

Вы можете исправить это, создав «адаптер» в основном для создания конкретного класса, который расширяет ваш базовый класс, реализует абстрактные методы, но ничего с ними не делает. Затем вы можете автоматически подключить эту реализацию и протестировать ее. Однако ваш абстрактный класс уже должен быть протестирован из-за того, что вы тестируете отчеты 1 и 2. Если ошибки все еще возникают с вашим базовым классом, это означает, что логика, которую вы не используете, вызывает ошибки, что в любом случае является плохой практикой. также с помощью инструмента тестового покрытия вы можете таким образом обнаружить неиспользуемый код.

person G-Man    schedule 12.04.2013
comment
Вы абсолютно правы. Прочитав ваш ответ, я еще раз посмотрел и, конечно же, немного неправильно понял проблему. Все конкретные классы расширяют BaseReport и реализуют метод export(), но метод export() происходит не от BaseReport, а скорее от интерфейса IReport, который реализуют BaseReport и все конкретные отчеты. Таким образом, нет необходимости тестировать метод export() в BaseReport, потому что у него его нет! Поскольку я уже протестировал метод export() каждого конкретного класса, моя работа выполнена. Большое спасибо за помощь. - person Robert Bowen; 12.04.2013