1. 写在前面
碰到过三种情况导致@Value获取不到配置值
- 变量被关键字static修饰
- 类没有使用@Component及其衍生标签修饰
- 在Bean初始化时构造方法中引用被@Value修饰的变量
如果不是以上三种情况那么这篇博文就没法给你提供帮助了。
需要获取的配置如下
kafka:
bootstrap:
servers: 192.168.202.131:9092
servers:
first:
topic: "first_topic"
group: "first_group"
我的测试项目是springboot的,如果是普通spring项目的application.properties文件也是类似
2. 变量被关键字static修饰
代码如下
package com.coline.codeskills.kafka;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author: Coline
* @ClassName: TestValue
* @Date: 2020/3/1 23:58
* @Description: test @Value Tag
*/
@Component
public class TestValue implements InitializingBean {
@Value("${kafka.bootstrap.servers}")
private String kafkaServers;
@Value("${kafka.servers.first.topic}")
private static String topic;
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(kafkaServers);
System.out.println(topic);
}
}
可以看到被static修饰的参数使用@Value无法获取到配置值
3. 类没有使用@Component及其衍生标签修饰
因为@Value是在AbstractAutowireCapableBeanFactory类的doCreateBean方法中进行初始化,即交由Spring容器进行处理,如果没有@Component及其衍生注解注释Spring无法识别,导致无法获取到配置值。
4. 在Bean初始化时构造方法中引用被@Value修饰的变量
代码如下
package com.coline.codeskills.kafka;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author: Coline
* @ClassName: TestValue
* @Date: 2020/3/1 23:58
* @Description: test @Value Tag
*/
@Component
public class TestValue {
@Value("${kafka.bootstrap.servers}")
private String kafkaServers;
@Value("${kafka.servers.first.topic}")
private static String topic;
public TestValue(){
System.out.println(kafkaServers);
}
}
如图,bean初始化时在构造方法中无法获取到@Value修饰的参数值
解决方法:
如果需要在bean初始化时获取参数值,那么我们可以使用@Config注解在bean初始化时获取到,代码如下:
package com.coline.codeskills.common.config;
import com.coline.codeskills.kafka.TestValue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* @author: Coline
* @ClassName: TestValueConfig
* @Date: 2020/3/2 0:44
* @Description: TODO
*/
@Configuration
public class TestValueConfig {
@Value("${kafka.bootstrap.servers}")
private String kafkaServers;
@Primary
@Bean
public TestValue testValue(){
TestValue testValue = new TestValue();
return testValue;
}
}