Автоматическое подключение списка весной, без настройки

#spring #autowired

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

Вопрос:

Как я могу автоматически подключить список, используя java, без настройки?

Допустим, у меня есть следующие классы:

 public abstract class A {
    public abstract doStuff();
}

public class B extends A {
    @Override
    public void doStuff() {
        System.out.println("I'm B");
    }
}

public class C extends A {
    @Override
    public void doStuff() {
        System.out.println("I'm C");
    }
}
  

И у меня есть класс

 public class Aggregator {
    @Autowired
    private List<A> stuffDoers;
    private void doAllStuff() {
        for(A a:stuffDoers) {
            a.doStuff();
        }
    }
}
  

Как я могу автоматически подключить часть реализации A к Aggregator без настройки списка в XML?

РЕДАКТИРОВАТЬ: я ищу способ управлять элементами списка

Ответ №1:

@Autowired всегда работает с экземплярами класса, а не с типами. Вы определили 3 типа: A , B и C , но не создали из них никаких экземпляров.

Для автоматического подключения вам необходимо создать эти экземпляры, а также зарегистрировать их в Spring. Здесь используется конфигурация XML или Java config. По сути, это короткая форма для создания экземпляров, зарегистрированных в Spring. Таким образом, вы можете указать:

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ApplicationConfiguration {

    @Bean
    public B someA() {
        return new B();
    }

    @Bean
    public C anotherA() {
        return new C();
    }

    @Bean
    public B evenMoreA() {
        return new B();
    }
}
  

Это дает вам 3 независимых компонента экземпляра (не список). Дополнительные сведения см. в разделе Конфигурация контейнера на основе Java.

Теперь Spring выполнит работу по поиску всех компонентов типа A в этих пакетах и правильно заполнит ваш Aggregator класс всеми тремя компонентами.

ПРИМЕЧАНИЕ: эти компоненты не обязательно должны находиться в одном файле. Они могут быть объявлены в любом месте ваших @ComponentScan пакетов.


Как было задано в комментарии, что делать, если вы хотите иметь только некоторые из этих экземпляров?

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

Конечно, если вам нужен только один компонент, тогда, как обычно, вы должны автоматически подключить его, используя @Qualifier и указав имя компонента. В этом случае вы не используете a List , только переменную типа A .

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

1. Я спросил, как это сделать без настройки, только на java.

2. @user1050389 достаточно справедливо, добавит пример JavaConfig.

3. Вы упомянули, что это дает три независимых компонента, а не список. Будет ли это работать, если эти независимые компоненты будут автоматически подключены в виде списка? В противном случае это не отвечает на вопрос.. Хорошо, я вижу, вы также ссылались на это. Спасибо!

4. Но что, если я хочу иметь только некоторые из этих экземпляров?

5. @user1050389 ответил на ваш дополнительный вопрос в качестве редактирования. Проверьте ответ.