【问题标题】:Spring autowiring order and @PostConstructSpring自动装配顺序和@PostConstruct
【发布时间】:2016-10-30 07:32:33
【问题描述】:

我对 Spring 中的自动接线顺序和 @PostConstruct 逻辑有疑问。例如下面的演示代码我有一个主要的 Spring Boot 类:

@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 被调用

在 Bean B 中调用 print me

beanb 被调用


我的问题是如何像上面的场景一样逐步进行自动装配?
以及如何在不先调用@PostConstruct 的情况下调用beanbprintMe() 方法?

【问题讨论】:

    标签: java spring spring-bean


    【解决方案1】:

    下面应该是可能的顺序

    1. beanb 开始自动连线
    2. Beanb 的类初始化期间,beana 开始自动装配
    3. 一旦创建了beana,就会调用@PostConstruct,即beana 的init()
    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 reference manual 解释了如何解决循环依赖关系。 bean 先被实例化,然后相互注入。

    【讨论】:

    【解决方案2】:

    您的答案是正确的,如您的问题所示。

    现在了解 Notation @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 类中,您尝试注入同样在您的控制台项目中定义的BeanA 类的对象。

    所以,在您的Demo1Application 中注入 BeanB 类的对象必须需要注入 BeanA 类的对象。 现在BeanA首先创建了类对象。

    现在,如果您看到 Your Class 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");
    

    【讨论】:

      猜你喜欢
      • 2017-10-31
      • 1970-01-01
      • 2015-02-24
      • 2018-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-13
      相关资源
      最近更新 更多