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");