Я впервые изучаю Spring Framework и DI и пробую небольшое тестовое приложение с Spring-boot 1.2.0 (ограничение проекта из-за версии Spring Framework, требуемой для 4.1.x), я создал BookBean, который имеет два атрибута: заголовок строки и список авторов. По-видимому, DI вводит заголовок как единственный член списка, и я абсолютно не понимаю, почему.
Я добавил некоторые записи в журнал для методов, помеченных @Bean, чтобы увидеть, когда они вызываются, плюс конструктор BookBean, и я заметил, что метод String вызывается ПОСЛЕ вызова конструктора:
[2019-04-29 14:46:05.631] boot - 3888 INFO [main] --- CollectionConfig: returning title: [A sample book]
[2019-04-29 14:46:05.637] boot - 3888 INFO [main] --- BookBean: construction called
[2019-04-29 14:46:05.649] boot - 3888 INFO [main] --- CollectionConfig: returning authors: [[John, Adam, Harry]]
Это заставляет меня верить, что DI не имеет доступного bean-компонента List при попытке создать BookBean, и «делает следующее лучшее», возвращая List, введенный с единственным известным ему String-бином: title.
В свою очередь, это заставило меня поверить, что я, возможно, неправильно делаю всю автопроводку, и что я не могу выстроить автопроводку по типу / имени в соответствии с запросом. Насколько я понимаю, по умолчанию autowire - это Type, и что конструктор должен попытаться найти bean-компоненты двух разных типов: String и List, но я попытался аннотировать bean-компоненты с помощью @Bean (name = "title" / "авторы" ) безуспешно. Если я также попытаюсь аннотировать параметры конструктора с помощью @Qualifier («title» / «авторы»), я получаю следующую ошибку:
[2019-04-29 14:54:25.847] boot - 20824 INFO [main] --- CollectionConfig: returning title: [A sample book]
[2019-04-29 14:54:25.853] boot - 20824 WARN [main] --- AnnotationConfigEmbeddedWebApplicationContext: Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookBean' defined in URL [jar:file:/C:/dev/Repos/branches/branch_rest_remake/branch_2019_04_11/webapp/target/webapp-0.0.1-SNAPSHOT.jar!/com/company/spring/webapp/domain/BookBean.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [java.util.List]: : No qualifying bean of type [java.lang.String] found for dependency [collection of java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=authors)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [collection of java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=authors)}
Это мои классы: (РЕДАКТИРОВАТЬ - удалены экземпляры Logger из примера, но они есть в коде)
@RestController
@RequestMapping("/")
public class DummyController {
@Autowired
private BookBean bookBean;
@RequestMapping("/di")
String dummyDependencyInjection() {
logger.info("called /di");
return bookBean.printAuthors();
}
}
@Configuration
public class CollectionConfig {
@Bean
public String title() {
String title = "A sample book";
logger.info("returning title: ["+title+"]");
return title;
}
@Bean
public List<String> authors() {
List<String> authors = Arrays.asList("John", "Adam", "Harry");
logger.info("returning authors: ["+authors+"]");
return authors;
}
}
@Component
public class BookBean {
private String title;
private List<String> authors;
@Autowired
public BookBean(String title, List<String> authors) {
logger.info("construction called");
this.title = title;
this.authors = authors;
}
public String printAuthors() {
logger.info("printAuthors called");
return "Authors in "+ title + "\n"+authors;
}
}
Без аннотаций @Qualifier bean-компонент создается с заголовком: «Образец книги» и авторы: [«Образец книги»], когда фактическое значение для авторов должно быть: [«Джон», «Адам», « Гарри "]
С аннотацией @Qualifier просто не удается загрузиться.