@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中核心类的注入顺序

image

源码

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


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

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

分析

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

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

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

posted @ 2023-09-09 14:52  sunpeiyu  阅读(1647)  评论(0编辑  收藏  举报