简单公司网站互联网广告优势
本期目录
- 一、 问题背景
- 二、 问题原因
- 三、 解决方法
一、 问题背景
今天碰到的问题是用 @Value 注解无法注入配置文件 application.yml 中的配置值。
检查过该类已经交给 Spring 容器管理了,即已经在类上加了 @Configuration 和 @ConfigurationProperties(prefix = "xxx") 注解了。但还是注入失败。
下面是配置文件 application.yml 中要注入的配置值:
student: name: Tomage: 21
问题伪代码如下:
@Configuration
@ConfigurationProperties(prefix = "student")
public class StudentConfig {@Value("${student.name}")private String name;@Value("${student.age}")private int age;private Map<Long, Student> stuMap = new HashMap<>();// 使用空参构造器初始化stuMappublic StudentConfig() {stuMap.put(1001L, new Student(name, age));}
}
看起来没有问题,但当我获取 stuMap 中的 Student 对象时,却发现其两个属性 name 为 null 、age = 0 。
我明明已经通过 @Value 注入配置文件 application.yml 中的值了呀,为什么会注入失败呢?
二、 问题原因
上面的代码之所以注入失败,错误点在于我使用了构造器来初始化 stuMap 。要知道为什么,首选要知道 Spring 容器中 Bean 的生命周期。
Spring 创建 Bean 的过程如下:
构造器 --> 自动注入 (包括 @Value 和 @Autowired ) --> @PostConstruct 修饰的初始化方法
从上面的执行顺序就不难看出,构造器中的方法首先被执行,此时两个属性 name 和 age 都还没被注入呢,自然就是 null 和 0 ;构造器方法执行完毕后,才到自动注入,这时候两个属性 name 和 age 才被赋值,但已经晚了。
三、 解决方法
根据Spring 创建 Bean 的执行顺序:
构造器 --> 自动注入 (包括 @Value 和 @Autowired ) --> @PostConstruct 修饰的初始化方法
只要把原来写在构造器中的初始化代码,写到一个用 @PostConstruct 修饰的方法中即可。
修改后的代码就能成功注入配置文件 application.yml 中的值了。
@Configuration
@ConfigurationProperties(prefix = "student")
public class StudentConfig {@Value("${student.name}")private String name;@Value("${student.age}")private int age;private Map<Long, Student> stuMap = new HashMap<>();// 使用@PostConstruct注解初始化stuMap@PostConstructpublic void initStuMap() {stuMap.put(1001L, new Student(name, age));}
}
以上就是我工作中遇到的问题了,希望对你有帮助。
