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
Spring autowiring order and @PostConstruct
提问by cacert
I have a question about auto-wiring order and @PostConstruct
logic in Spring. For example following demo code I have a main Spring Boot class:
我有一个关于@PostConstruct
Spring 中自动接线顺序和逻辑的问题。例如下面的演示代码我有一个主要的 Spring Boot 类:
@SpringBootApplication
public class Demo1Application {
@Autowired
BeanB beanb;
public static void main(String[] args) {
SpringApplication.run(Demo1Application.class, args);
}
}
and 2 @Service
Definitions:
和 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 beanb
is called without calling its @PostConstruct
first?
我的问题是如何像上面的场景一样逐步进行自动装配?
以及如何printMe()
在beanb
不调用其@PostConstruct
第一个方法的情况下调用方法?
回答by Mudassar
Below should be possible sequence
下面应该是可能的顺序
beanb
starts to get autowired- During class initialization of
Beanb
, beana starts to get autowired - Once beana gets created the
@PostConstruct
i.e.init()
of beana gets called - Inside
init()
,System.out.println("bean a is called");
gets called - Then
b.printMe();
gets called causingSystem.out.println("print me is called in Bean B");
to execute - Having the
beana
completed the@PostConstruct
i.e.init()
ofbeanb
gets called - Then
System.out.println("beanb is called");
gets called
beanb
开始自动装配- 在 的类初始化期间
Beanb
,beana 开始自动装配 - 一旦 beana 被创建,bean的
@PostConstruct
ieinit()
就会被调用 - 在里面
init()
,System.out.println("bean a is called");
被调用 - 然后
b.printMe();
被调用导致System.out.println("print me is called in Bean B");
执行 - 具有
beana
完成@PostConstruct
即init()
中beanb
被调用 - 然后
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 @Autowired
Objects 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 BeanB
class you are trying to inject the Object of Class BeanA
which is also defined in your console Project.
在BeanB
课堂上,您正尝试注入BeanA
也在您的控制台项目中定义的类对象。
So, In Your Demo1Application
to inject a Object of Class BeanB
there must need to inject a Object of class BeanA
.
Now BeanA
Class 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 BeanA
method bind with @PostContruct
annotation 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");