@Value不生效原因排查

问题代码区域

在@Configuration+@Bean实现注入bean对象里面调用注入的@Value标识的值。

@Configuration
public class InitRedisConfig {
 
    @Value("${spring.redis.host}")
    private String redisHost;
    @Value("${spring.redis.port}")
    private Integer redisPort;
    @Value("${spring.redis.database}")
    private Integer redisDatabase;
 
    /**
     * 所有对Redisson的使用都是通过RedissonClient对象
     * @return
     */
    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient(){
        // 创建配置 指定redis地址及节点信息
        Config config = new Config();
        String redisAddr = "redis://" + redisHost + ":" + redisPort;
        config.useSingleServer()
                .setAddress(redisAddr)
                .setPassword(null)
                .setDatabase(redisDatabase);
 
        // 根据config创建出RedissonClient实例
        return Redisson.create(config);
    }
}

错误日志

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.redis.host' in value "${spring.redis.host}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:180) ~[spring-core-5.3.16.jar:5.3.16]
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) ~[spring-core-5.3.16.jar:5.3.16]
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239) ~[spring-core-5.3.16.jar:5.3.16]
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) ~[spring-core-5.3.16.jar:5.3.16]
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:191) ~[spring-context-5.3.16.jar:5.3.16]
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:936) ~[spring-beans-5.3.16.jar:5.3.16]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1330) ~[spring-beans-5.3.16.jar:5.3.16]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309) ~[spring-beans-5.3.16.jar:5.3.16]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:656) ~[spring-beans-5.3.16.jar:5.3.16]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639) ~[spring-beans-5.3.16.jar:5.3.16]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.16.jar:5.3.16]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.16.jar:5.3.16]
    ... 40 common frames omitted

spring中核心类的注入顺序

源码

@Value注入的后置处理器:AutowiredAnnotationBeanPostProcessor
注入的位置:

可以看出来AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition方法是在上面步骤中的第四步执行,会在其中扫描@Value注解,并且会将注解标识的bean注入。


@Configuration+@Bean注入的后置处理器:ConfigurationClassPostProcessor

可以看出来ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry方法是在上面步骤中的第一步执行,会在其中扫描@Bean注解,并且会将注解标识的bean注入。

分析

  • @Value这个注解并没有失效,属性值仍然会注入到变量中。

  • @Value注入的值无法读取,主要还是在于@Value注入的值顺序在@Configuration+@Bean的后面,所以才会出现读取到的@Value标记的值为null。

  • 如果不是@Value,而是使用@Autowired去注入,那么由于顺序问题,效果也是一样的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容