Spring @Value靜態(tài)屬性無法注入
場景
數據庫存的是相對路徑,服務推送等的host值填充
為了方便采用Spring配置文件@Value注入動態(tài)注入
配置文件
xxx.host=http:xxxx.com
工具類
@Component
public class XXXUtil {
? ?@Value("xxx.host")
? ?private static String XXXXHOST;
? ?private XXXUtil() {}
? ?
? ?public static String getXXXHost() {
? ? // 方法體省略
? ?}
}
看起來很簡單的一個開發(fā)任務,結果一測試發(fā)現host值一直未null。
明顯就是屬性沒有注入成功。
調試發(fā)現去掉static
private String XXXXHOST
可以!?。?/p>
未注入的原因
其實原因很簡單,認真思考下就知道原因。
@Value
注解是依賴于屬性的set
方法進行注入的,而static
修飾的屬性是類屬性,不存在set
方法
解決方法
1、set方法手動賦值
利用非靜態(tài)setter
方法注入靜態(tài)變量, 會在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注釋的方法 可以有任何訪問級別,但不能是靜態(tài)的
@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