为什么?因为可能出现以为有值,但实际无值的情况。
用一个例子具体来说明:
示例
Bean01.java
package demo.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class Bean01 {
@Autowired
private Bean03 bean03;
public void process() {
System.out.println("Bean01.process 获取 bean03.data 值: " + bean03.getData());
}
@PostConstruct
private void ps() {
System.out.println("Bean01 在 PostConstruct 中获取 bean03.data 值: " + bean03.getData());
}
}
Bean02.java
package demo.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class Bean02 {
@Autowired
private Bean03 bean03;
@PostConstruct
private void ps() {
System.out.println("Bean02 在 PostConstruct 中设置 bean03.data 值");
bean03.setData("你好");
}
}
Bean03.java
package demo.bean;
import org.springframework.stereotype.Component;
@Component
public class Bean03 {
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
Main.java
package demo;
import demo.bean.Bean01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(Main.class);
Bean01 bean01 = ctx.getBean(Bean01.class);
bean01.process();
}
}
执行结果与分析
运行 Main 类,输出:
Bean01 在 PostConstruct 中获取 bean03.data 值: null
Bean02 在 PostConstruct 中设置 bean03.data 值
Bean01.process 获取 bean03.data 值: 你好
注意,第1行的输出,就是以为有值,实际无值(值为 null)的情况,在调用 process 构造函数时,才有值。
为什么执行 Bean01 在 @PostConstruct 修饰的 ps 函数时,未获取到值?
我们先看下依赖关系:
Bean01 Bean02
\ /
\ /
\ /
Bean03
Bean01 和 Bean02 无直接依赖,只是共同依赖了 Bean03 。按照命名升序, Bean01 的 @PostContruct 会比 Bean02 的 @PostContruct 先执行,自然获取不到值
为什么执行 Bean01 的 process 方法时,获取到了值?
因为此时 spring 容器已经初始化完成,所有的 @PostContruct 都已经执行完了。
那么,如何让Bean01 在 @PostConstruct 修饰的 ps 函数时,获取到值 ?
让 Bean02 比 Bean01先初始化完成就行。比如用显式声明 Bean01 依赖 Bean02:
// 省略部分内容
import org.springframework.context.annotation.DependsOn;
@Component
@DependsOn("bean02")
public class Bean01 {
此时执行 Main 类,输出:
Bean02 在 PostConstruct 中设置 bean03.data 值
Bean01 在 PostConstruct 中获取 bean03.data 值: 你好
Bean01.process 获取 bean03.data 值: 你好
虽然解决了,但是不建议这样做。因为 在 @PostConstruct 设置其他 Bean 中的变量
本身就不是一个好的实践。