@ConfigurationProperties、@Value注入失效但单元测试正常问题求助
问题根因
你在Controller中通过new MyService()手动创建了MyService实例,只有Spring容器管理的Bean才会触发@Autowired、@Value、@ConfigurationProperties的注入逻辑,手动new的对象完全脱离Spring管控,自然所有注入注解都不会生效。
你的单元测试能正常运行,是因为@SpringBootTest会加载完整的Spring上下文,你注入的MyProperties本身就是容器管理的Bean,所以属性赋值正常。
修复方案
1. 优先使用Spring注入获取业务类实例(推荐)
不要手动new MyService,改为在Controller中注入Spring管理的MyService实例,修改后代码如下:
@Slf4j @RestController // 本身已经是Spring组件注解,无需重复加@Service public class Main { @Autowired private MyProperties props; @Value("localhost") private String host; // 注入Spring管理的MyService实例 @Autowired private MyService myService; @GetMapping("/post") public void post() { log.info(host + props); // 输出正常 myService.post(); // 调用容器内实例,所有注入属性均有值 } }
2. 特殊场景需要手动获取Bean的方案
如果确实有场景需要手动获取Spring容器中的Bean,可以通过ApplicationContext获取:
// 先获取Spring上下文,再调用getBean方法获取实例 MyService myService = applicationContext.getBean(MyService.class); myService.post();
额外排查点(如修改后仍有问题可校验)
- 确认启动类所在包路径是所有业务类的父包:SpringBoot默认会扫描启动类所在包及其子包下的所有带@Component、@Service、@RestController等注解的类,若业务类不在扫描范围内,也会导致注入失败。
- 不需要给MyProperties加@Component的情况下,也可以在@EnableConfigurationProperties注解中指定属性类:
@EnableConfigurationProperties(MyProperties.class),两种方式二选一即可。
内容的提问来源于stack exchange,提问作者Samuel Waithaka
相关产品推荐
相关产品推荐

