Spring порядок автопостановки и @PostConstruct
У меня вопрос о порядке автоматической проводки и логике @PostConstruct
в Spring. Например, следующий демо-код у меня есть основной Spring класс загрузки:
@SpringBootApplication
public class Demo1Application {
@Autowired
BeanB beanb;
public static void main(String[] args) {
SpringApplication.run(Demo1Application.class, args);
}
}
и 2 @Service
Определения:
@Service
public class BeanB {
@Autowired
private BeanA beana ;
@PostConstruct
public void init(){
System.out.println("beanb is called");
}
public void printMe(){
System.out.println("print me is called in Bean B");
}
}
@Service
public class BeanA {
@Autowired
private BeanB b;
@PostConstruct
public void init(){
System.out.println("bean a is called");
b.printMe();
}
}
и у меня есть следующий вывод:
bean a называется
print me вызывается в Bean B
beanb называется
Мой вопрос заключается в том, как аутоустановка происходит шаг за шагом, как сценарий выше?
И как метод printMe()
beanb
вызывается без вызова его @PostConstruct
первым?
Ответы
Ответ 1
Ниже должна быть возможная последовательность
-
beanb
начинает автообновляться
- Во время инициализации класса
beanb
, beana начинает получать autwired
- Как только beana будет создан,
@PostConstruct
i.e. init()
beana будет вызван
- Внутри
init()
, System.out.println("bean a is called");
вызывается
- Затем
b.printMe();
получает вызов, вызывающий System.out.println("print me is called in Bean B");
для выполнения
- После завершения
beana
@PostConstruct
i.e. init()
из beanb
вызывается
- Затем
System.out.println("beanb is called");
получает вызов
В идеале то же самое можно лучше наблюдать отладчиком в eclipse.
Справочное руководство Spring объясняет, как разрешены круговые зависимости. Сначала создаются beans, затем вставляются друг в друга.
Ответ 2
Ваш ответ правильный, как показано в вашем вопросе.
Теперь ознакомьтесь с концепцией нотации @Autowired
. Все объекты @Autowired
инициализируются и загружаются в память сразу после завершения загрузки класса.
Теперь вот ваш SpringBootApplication
@SpringBootApplication
public class Demo1Application {
@Autowired
BeanB beanb; // You are trying to autowire a Bean class Named BeanB.
Здесь, в приведенном выше Консольном приложении, которое вы пишете, попробуйте автоувеличить и ввести объект типа BeanB
.
Теперь вот ваше определение BeanB
@Service
public class BeanB {
@Autowired
private BeanA beana ;
В классе BeanB
вы пытаетесь ввести Object of Class BeanA
, который также определен в вашем консольном проекте.
Итак, In Your Demo1Application
для ввода объекта класса BeanB
необходимо добавить объект класса BeanA
.
Теперь BeanA
Сначала создается объект класса.
Теперь, если вы видите определение своего класса BeanA
@Service
public class BeanA {
@Autowired
private BeanB b;
@PostConstruct // after Creating bean init() will be execute.
public void init(){
System.out.println("bean a is called");
b.printMe();
}
}
Итак, после ввода метода Object BeanA
bind с @PostContruct
будет выполняться аннотация.
Итак, поток выполнения будет...
System.out.println("bean a is called");
System.out.println("print me is called in Bean B");
System.out.println("beanb is called");