Я думаю, это потому, что Spring сначала должен создать экземпляр вашего SomeBean
класса, а затем попытается автоматически связать FirstBean
через отражение, потому что вы добавили @Autowired
аннотацию в поле.
Выпытается получить доступ к зависимости FirstBean
в конструкторе SomeBean
, но когда вызывается конструктор SomeBean
, при создании контекста зависимость FirstBean
равна нулю, потому что Spring еще не подключил эту зависимость автоматически - он попытается автоматически подключить еечерез отражение после создания объекта.Вот почему вы получаете NullPointerException
там.Та же самая ситуация происходит с вашим SomeBean
классом - выберите один подход.
Кроме того, странно, что вы создаете классы, аннотированные @Configuration
и @Component
.Пожалуйста, обратитесь к этому вопросу SO , чтобы увидеть возможные ошибки.
Более того, в вашей конфигурации есть некоторые проблемы.Вы аннотируете FirstBean
аннотацией @Component
и все еще создаете аннотированный метод @Bean
, который возвращает экземпляр этого класса.Вы должны выбрать один метод - вы создаете его для контекста приложения с помощью аннотации @Bean
или аннотируете этот класс с помощью @Component
, и вы разрешаете компонентному сканированию автоматически создавать его для вас.
EDIT :
Вы должны решить, хотите ли вы использовать @ComponentScan
или вы хотите создать ваши bean-компоненты для контекста с помощью аннотации @Bean
- сейчас вы смешиваете разные типы и получаете ошибки для повторяющихся определений bean-компонентовпри попытке автоматической передачи по типу, потому что в вашей текущей реализации будет 2 компонента для SomeBean
и 2 компонента для FirstBean
в вашем контексте - они будут иметь только разные идентификаторы.Обратите внимание, что ошибка, на которую я указывал при ожидании NPE, не имеет к этому никакого отношения.Я предложу решение с использованием автоматического сканирования пакетов:
FirstBean class
@Component
public class FirstBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "FirstBean [name=" + name + "]";
}
}
SomeBean class
@Component
public class SomeBean {
private FirstBean fb;
@Autowired
public SomeBean(FirstBean firstBean) {
this.fb = firstBean;
this.fb.setName("Some Name");
}
public void print() {
this.fb.toString();
}
}
Класс MyConfig
@Configuration
@ComponentScan(basePackages = { "com.example" })
public class MyConfig {
}
Класс MainDriver
@Component
public class MainDriver {
@Autowired
private Environment env;
@Autowired
protected ConfigurableEnvironment cenv;
@Autowired
ApplicationContext ctx;
@Autowired
private SomeBean sb;
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
MainDriver l = ctx.getBean(MainDriver.class);
System.out.println("In main() the ctx is " + ctx);
l.test();
}
public void test() {
System.out.println("hello");
sb.print();
}
}