#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 ответил на ваш дополнительный вопрос в качестве редактирования. Проверьте ответ.