Реализацию, описанную в статье можно найти на GitHub project.
Зададим общий интерфейс.
public interface Processor {
String process(String str);
}
И пару spring beans, которые имплементируют данный интерфейс.
@Component
public class RemoveSpaceProcessor implements Processor {
@Override
public String process(String str) {
return str.replace(" ", "");
}
}
@Component
public class UpperCaseProcessor implements Processor {
@Override
public String process(String str) {
return str.toUpperCase();
}
}
В таком случае при инжектировании в spring bean коллекции, типизированной созданным интерфейсом, все бины, имплементирующие данный интерфейс, будут добавлены в эту коллекцию автоматически.
@SpringBootApplication
public class ListBeanApplication implements ApplicationRunner {
private final List<Processor> processorList;
@Value("${stringValue}")
private String value;
public ListBeanApplication(List<Processor> processorList) {
this.processorList = processorList;
}
Добавление бинов также можно организовать в ассоциативный массив. Для этого определяем следующий типизированный интерфейс
Map<String, Processor> processorMap;
По умолчанию, если не задано название бина, будет использоваться название класса. Таким образом все бины, имплементирующие интерфейс Processor будут добавлены в эту коллекцию.
Tест, проверяющий данный кейс
@Test
void checkMap() {
assertThat(listBeanApplication.getProcessorMap()).hasSize(2);
assertThat(listBeanApplication.getProcessorMap()
.get("removeSpaceProcessor")
.process("Test String"))
.isEqualTo("TestString");
}