【Spring】@Value注入配置文件 application.yml 中的值失败怎么办



一、 问题背景

今天碰到的问题是用 @Value 注解无法注入配置文件 application.yml 中的配置值。

检查过该类已经交给 Spring 容器管理了,即已经在类上加了 @Configuration@ConfigurationProperties(prefix = "xxx") 注解了。但还是注入失败。

下面是配置文件 application.yml 中要注入的配置值:

student: 
  name: Tom
  age: 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<>();

	// 使用空参构造器初始化stuMap
	public StudentConfig() {
    
    
		stuMap.put(1001L, new Student(name, age));
	}
}

看起来没有问题,但当我获取 stuMap 中的 Student 对象时,却发现其两个属性 namenullage = 0 。
我明明已经通过 @Value 注入配置文件 application.yml 中的值了呀,为什么会注入失败呢?


二、 问题原因

上面的代码之所以注入失败,错误点在于我使用了构造器来初始化 stuMap 。要知道为什么,首选要知道 Spring 容器中 Bean 的生命周期。

Spring 创建 Bean 的过程如下:

构造器 --> 自动注入 (包括 @Value@Autowired ) --> @PostConstruct 修饰的初始化方法

从上面的执行顺序就不难看出,构造器中的方法首先被执行,此时两个属性 nameage 都还没被注入呢,自然就是 null 和 0 ;构造器方法执行完毕后,才到自动注入,这时候两个属性 nameage 才被赋值,但已经晚了。


三、 解决方法

根据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
	@PostConstruct
	public void initStuMap() {
    
    
		stuMap.put(1001L, new Student(name, age));
	}
}

以上就是我工作中遇到的问题了,希望对你有帮助。

猜你喜欢

转载自blog.csdn.net/Sihang_Xie/article/details/129064943