弹簧自动布线顺序和@PostConstruct

2022-09-01 09:02:30

我有一个关于春季自动布线顺序和逻辑的问题。例如,下面的演示代码我有一个主要的Spring Boot类:@PostConstruct

@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();
    }
}

我有以下输出:

豆a被称为

打印我被称为豆B

豆子被称为


我的问题是自动布线是如何像上面的场景一步一步地进行的?
如何调用 的方法 在不调用其第一个的情况下调用?printMe()beanb@PostConstruct


答案 1

下面应该是可能的顺序

  1. beanb开始自动布线
  2. 在 的类初始化期间,beana 开始自动布线Beanb
  3. 一旦豆豆被创建,即 的豆豆被调用@PostConstructinit()
  4. 内部 ,被调用init()System.out.println("bean a is called");
  5. 然后被调用导致执行b.printMe();System.out.println("print me is called in Bean B");
  6. 已完成即 的被调用beana@PostConstructinit()beanb
  7. 然后被调用System.out.println("beanb is called");

理想情况下,eclipse 中的调试器可以更好地观察到相同的情况。

Spring 参考手册解释了如何解决循环依赖关系。首先将豆子实例化,然后相互注入。


答案 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 ;

在类中,您正在尝试注入类的对象,该对象也在控制台项目中定义。BeanBBeanA

因此,在 Your 中,要注入类的对象,必须需要注入类的对象。现在首先创建类对象。Demo1ApplicationBeanBBeanABeanA

现在,如果您看到类的定义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@PostContruct

因此,执行流将是..

System.out.println("bean a is called");
System.out.println("print me is called in Bean B");
System.out.println("beanb is called");

推荐