如何使用@Value读取application.properties配置值提前赋值初始化实例变量
问题根因
你遇到的空值问题本质是Java类实例化顺序和Spring注入时机不匹配导致的:
测试类的成员变量初始化(也就是你写的new ClassA(valueFromApplicationProperties))会在Spring的@Value属性注入之前执行,此时配置值还没被赋值自然是null;而@Before方法是Spring上下文初始化、所有属性注入完成后才会执行,所以能正常拿到配置值。
解决方案(完全符合你要求的执行顺序)
方案1:手动控制初始化+注入逻辑(最灵活,顺序完全可控)
直接把ClassA的实例化和Mockito注入逻辑移到@Before方法中,严格按照你要的「配置赋值→初始化ClassA→注入ClassB」顺序执行:
@TestPropertySource("classpath:application.properties") public class Test { @Value("${valueFromApplicationProperties}") String valueFromApplicationProperties; // 不在声明处初始化,取消多余的@Autowired注解 ClassA a; @InjectMocks ClassB b; @Before public void setup() { // 此时@Value已经完成注入,value为有效值 // 1. 初始化ClassA,用Mockito.spy包装实现原@Spy的功能 a = Mockito.spy(new ClassA(valueFromApplicationProperties)); // 2. 手动触发Mockito注入逻辑,将a注入到b中 MockitoAnnotations.openMocks(this); // 后续你的测试初始化逻辑 System.out.println(valueFromApplicationProperties); } }
方案2:用Spring托管ClassA实例(不需要修改初始化逻辑)
如果不想手动处理注入,可以把ClassA注册为Spring测试上下文的Bean,Spring会自动保证@Value注入完成后再构造ClassA实例:
- 新增测试配置类
@Configuration public class TestConfig { @Value("${valueFromApplicationProperties}") private String configValue; @Bean public ClassA classA() { // Spring会先注入配置值再创建Bean,此处configValue一定非空 return new ClassA(configValue); } }
- 测试类引入配置即可
@Import(TestConfig.class) @TestPropertySource("classpath:application.properties") public class Test { @Spy @Autowired ClassA a; @InjectMocks ClassB b; @Before public void setup() { System.out.println(valueFromApplicationProperties); } }
注意事项
不要在成员变量声明处直接初始化依赖Spring注入属性的对象,成员变量初始化的时机是测试类实例创建时、Spring注入动作执行前,必然拿不到注入的属性值。
内容的提问来源于stack exchange,提问作者Snookums
相关产品推荐
相关产品推荐

