如何在调用构造方法前完成Spring @Value注解标注属性的注入?
Spring @Value属性提前注入问题解答
首先明确Spring Bean的默认生命周期顺序:先调用构造方法完成对象实例化,再执行字段注入(包括@Value、@Autowired等注解标注的字段)。你现在遇到的空值问题是必然结果:
- 实例变量
instanceProp的初始化是在对象分配内存后、构造方法执行前触发,此时还没进入Spring的属性注入阶段 - 构造方法执行时属性注入还未开始,
prop1必然为null
两个需求均可实现,但是不能通过字段注入的方式实现构造前的字段赋值,可选择以下两种方案:
方案1:构造注入(最推荐,两个需求都能满足)
将@Value注解放到构造方法入参上,Spring在调用构造方法时会自动把配置值作为入参传入,你可以在构造方法中完成prop1赋值和instanceProp的初始化:
package com.demo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class WirableComponent { String prop1; String instanceProp; public WirableComponent(@Value("${prop1}") String prop1) { this.prop1 = prop1; this.instanceProp = getInstanceProp(); System.err.println("no-args WirableComponent Constructor invoked"); System.err.println("value prop1: " + prop1); // 已拿到配置值 System.err.println("value instanceProp: " + instanceProp); // 已正常赋值 } public String getInstanceProp() { System.err.println("value prop1: " + prop1); return prop1; } }
方案2:@PostConstruct初始化(仅满足getInstanceProp提前注入的需求)
如果不需要在构造方法中使用prop1,可以把初始化逻辑放到@PostConstruct标注的方法中,该方法会在Spring完成所有属性注入后自动触发:
package com.demo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; // Spring 6及以上版本替换为jakarta.annotation.PostConstruct @Component public class WirableComponent { @Value("${prop1}") String prop1; String instanceProp; public WirableComponent() { System.err.println("no-args WirableComponent Constructor invoked"); System.err.println("value prop1: " + prop1); // 此处还是null,构造阶段未执行属性注入 } @PostConstruct private void init() { this.instanceProp = getInstanceProp(); System.err.println("value prop1 in init: " + prop1); // 已拿到配置值 System.err.println("value instanceProp in init: " + instanceProp); // 已正常赋值 } public String getInstanceProp() { System.err.println("value prop1: " + prop1); return prop1; } }
补充说明
不存在任何方式可以让字段上标注的@Value在构造方法执行前完成注入:字段注入的本质是Spring拿到实例化后的对象,通过反射修改对象的字段值,必须先有实例(即构造方法执行完成)才能操作,不可能逆序执行。
内容的提问来源于stack exchange,提问作者samshers
相关产品推荐
相关产品推荐

