Java Spring 自动装配顺序和 @PostConstruct

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38068303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:59:16  来源:igfitidea点击:

Spring autowiring order and @PostConstruct

javaspringspring-bean

提问by cacert

I have a question about auto-wiring order and @PostConstructlogic in Spring. For example following demo code I have a main Spring Boot class:

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

@SpringBootApplication
public class Demo1Application {

    @Autowired
    BeanB beanb;

    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
    }
}

and 2 @ServiceDefinitions:

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

and I have the following output:

我有以下输出:

bean a is called

print me is called in Bean B

beanb is called

bean a 被称为

在 Bean B 中调用 print me

beanb 被称为


My question is how autowiring takes place step by step like a scenario above?
And how printMe()method of beanbis called without calling its @PostConstructfirst?


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

回答by Mudassar

Below should be possible sequence

下面应该是可能的顺序

  1. beanbstarts to get autowired
  2. During class initialization of Beanb, beana starts to get autowired
  3. Once beana gets created the @PostConstructi.e. init()of beana gets called
  4. Inside init(), System.out.println("bean a is called");gets called
  5. Then b.printMe();gets called causing System.out.println("print me is called in Bean B");to execute
  6. Having the beanacompleted the @PostConstructi.e. init()of beanbgets called
  7. Then System.out.println("beanb is called");gets called
  1. beanb开始自动装配
  2. 在 的类初始化期间Beanb,beana 开始自动装配
  3. 一旦 beana 被创建,bean的@PostConstructieinit()就会被调用
  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");被调用

Ideally the same can be better observed by a debugger in eclipse.

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

The Spring reference manualexplains how circular dependencies are resolved. The beans are instantiated first, then injected into each other.

Spring参考手册介绍了循环依赖是如何解决的。这些 bean 首先被实例化,然后相互注入。

回答by Vikrant Kashyap

Your Answer is Correct as you shown in Your question.

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

Now Getting the concept of Notation @Autowired. All @AutowiredObjects are initialized and loaded in memory just after class Loading is done.

现在得到 Notation 的概念@Autowired@Autowired在类加载完成后,所有对象都被初始化并加载到内存中。

Now here is your SpringBootApplication

现在这是你的 SpringBootApplication

@SpringBootApplication
public class Demo1Application {
    @Autowired
    BeanB beanb;   // You are trying to autowire a Bean class Named BeanB.

Here at above Console Application that you have write try to autowire and inject a object of type BeanB.

在上面您编写的控制台应用程序中,尝试自动装配并注入类型为 的对象BeanB

Now here is your definition of BeanB

现在这是你的定义 BeanB

@Service
public class BeanB {

    @Autowired
    private BeanA beana ;

In BeanBclass you are trying to inject the Object of Class BeanAwhich is also defined in your console Project.

BeanB课堂上,您正尝试注入BeanA也在您的控制台项目中定义的类对象。

So, In Your Demo1Applicationto inject a Object of Class BeanBthere must need to inject a Object of class BeanA. Now BeanAClass Object is Created First.

所以,在你Demo1Application注入一个类的对象时,BeanB必须注入一个类的对象BeanA。现在BeanA首先创建类对象。

Now if you see the definition of Your Class 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();
    }
}

So, After injecting the Object BeanAmethod bind with @PostContructannotation is going to execute.

因此,在注入BeanA带有@PostContruct注解的对象方法绑定后, 将执行。

So, execution flow will be..

所以,执行流程将是..

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