Spring @Value静态属性无法注入
场景
数据库存的是相对路径,服务推送等的host值填充
为了方便采用Spring配置文件@Value注入动态注入
配置文件
xxx.host=http:xxxx.com
工具类
@Component
public class XXXUtil {
@Value("xxx.host")
private static String XXXXHOST;
private XXXUtil() {}
public static String getXXXHost() {
// 方法体省略
}
}
看起来很简单的一个开发任务,结果一测试发现host值一直未null。
明显就是属性没有注入成功。
调试发现去掉static
private String XXXXHOST
可以!!!
未注入的原因
其实原因很简单,认真思考下就知道原因。
@Value
注解是依赖于属性的set
方法进行注入的,而static
修饰的属性是类属性,不存在set
方法
解决方法
1、set方法手动赋值
利用非静态setter
方法注入静态变量, 会在Spring
加载的时候进行属性注入
@Component
public class XXXUtil {
private static String XXXXHOST;
private XXXUtil() {}
@Value("xxx.host")
public void setHost(String host) {
XXXUtil.XXXXHOST = host;
}
public static String getXXXHost() {
// 方法体省略
}
}
2、构造方法赋值
和set
方法差不多
@Component
public class XXXUtil {
private static String XXXXHOST;
private XXXUtil() {}
@Value("xxx.host")
public XXXUtil(String host) {
XXXUtil.XXXXHOST = host;
}
public static String getXXXHost() {
// 方法体省略
}
}
3、@PostConstruct
@Component
public class MyComponent {
@Value("${xxx.host}")
private static final String CONSTANT_VALUE;
*// 省略其他代码*
}@Configuration
@DependsOn("myComponent")
public class StaticConstantInjectionConfig {
@Bean
public MyComponent myComponent() {
MyComponent myComponent = new MyComponent();
myComponent.setStaticConstantValue(CONSTANT_VALUE);
return myComponent;
}
// 省略其他代码
}
4、@PostConstruct
Spring 只调用一次用@PostConstruct注释的方法,就在 bean 属性的初始化之后。
用 @PostConstruct注释的方法 可以有任何访问级别,但不能是静态的
@Component
@Slf4j
public class XXXUtil {
private static String XXXXHOST;
private XXXUtil() {}
@Value("xxx.host")
private String hostStr;
@PostConstruct
public void init(){
XXXXHOST = hostStr;
}
public static String getXXXHost() {
// 方法体省略
}
}
5、SpringUtils
不过多写了,更多方法欢迎留言讨论!
总结
@Value
注解可以用来对Spring
容器中的bean