詳解Spring如何注入靜態(tài)變量
為什么 Spring 不可以注入靜態(tài)變量
@Autowired 不能注入 static 成員屬性
靜態(tài)變量和靜態(tài)方法屬于類,而 Spring 容器中管理的是對象,使用 @Autowired 注入的是容器中的對象實(shí)例,靜態(tài)變量和方法是不能直接使用 @Autowried 注入的。
Spring 不建議開發(fā)代碼中為靜態(tài)變量注入屬性值,類加載時會優(yōu)先加載靜態(tài)變量,此時 Spring 的上下文環(huán)境還沒有完成加載,因此不可以為靜態(tài)變量綁定值。
另一方面,在 @Autowired 注解注入掃描 Class 類原數(shù)據(jù)時,會直接忽略類的使用 static 關(guān)鍵字標(biāo)識的成員。
使用 @Value 讀取配置文件時,配置文件內(nèi)容會作為 Properties 對象的屬性管理在容器中,使用注解加載到變量上時就是使用容器注入的機(jī)制將配置內(nèi)容賦值給相應(yīng)屬性。
@Value 注解標(biāo)注靜態(tài)變量
如果 @Value 注解標(biāo)注在 static 或 final 變量,并不能將屬性值注入,最終得到的變量值是 null。
Spring 注入內(nèi)容到靜態(tài)變量中
@Value + set 方法注入靜態(tài)變量
如果想要為 static 變量注入值,可以間接的操作方式,比如可以通過注解標(biāo)注在 set 方法(非靜態(tài))上,使用 set 方法注入的方式將屬性值賦值到靜態(tài)變量中。
@Component public class Customer { ? ? private static String name; ? ? @Value("${customer.name}") ? ? public void setName(String name) { ? ? ? ? Customer.name = name; ? ? } }
定義靜態(tài)方法工具類時,則不建議在工具類中使用注入的內(nèi)容,因?yàn)楣ぞ哳惗x的是靜態(tài)方法,使用時容器并沒有加載完成,容易出現(xiàn) NPE 問題。
Properties 注入靜態(tài)變量
Properties 作為 java.util
包中用來讀取配置文件的類,其本身是一個 Hashtable,可以將 *.properties
配置文件內(nèi)容以鍵值對的形式存儲在對象中。
Properties 使用時可以通過 load() 方法自定義指定需要讀取的配置文件,通過流的方式讀取文件中內(nèi)容,并通過 getProperty() 方法讀取指定配置信息。
因?yàn)?Properties 是通過讀取文件內(nèi)容來獲取配置文件,不依賴 Spring 容器的加載,只要指定讀取配置文件后,就可以獲取到對應(yīng)的屬性,可以在加載類時賦值到靜態(tài)變量。
具體使用方法為
Properties 讀取文件工具類
public class PropertiesUtil { ? ?private static Properties readProperties(String configFile) { ? ? ? ?Properties properties = new Properties(); ? ? ? ?try { ? ? ? ? ? properties.load( new ClassPathResource(path).getInputStream()); ? ? ? } catch (IOException e) { ? ? ? ? ? ?e.printStackTrace(); ? ? ? } ? ? ? ?return properties; ? } }
使用 Properties 注入靜態(tài)變量
@Component public class Customer { ? ? private static Properties properties = PropertiesUtil.readProperties("application.properties"); ? ? private static String name = properties.getProperty("name"); }
Properties 作為 Java 工具包中讀取配置文件的類,可以讀取配置并賦值給靜態(tài)變量,但是 Properties 僅可以讀取 .properties
配置文件,而不可以解析 .yml
配置文件。
詳細(xì)的 Properties 使用方法可見:SpringBoot 使用 Properties 讀取配置文件
Environment 注入靜態(tài)變量
Spring 中有一個類 Environment
,它可以被認(rèn)為是當(dāng)前應(yīng)用程序正在運(yùn)行的環(huán)境,繼承了 PropertyResolver
接口,因此可以作為一個屬性解析器使用。
Environment 可以從容器中注入,并使用對象的 getProperty() 方法來獲取屬性值。
只要在類加載靜態(tài)屬性時獲取到初始化的 Environment 對象信息,就可以為靜態(tài)變量賦值。
可以通過 @Autowired + set 方法將 Environment 對象注入到靜態(tài)變量中,然后使用靜態(tài)變量獲取配置項(xiàng)即可。
@Component public class Customer { ? ?private static Environment env; ? ?@Autowired ? ?public void setEnvironment(Environment environment) { ? ? ? ?env = environment; ? } ? ?private static String name = ?env.getProperty("name"); }
Environment 可以讀取 .properties
配置文件和 .yml
配置文件,是更好的一種選擇。
綜述
綜上所述,有如下結(jié)論:
- 在 Spring 項(xiàng)目中不建議將內(nèi)容注入到靜態(tài)變量中,因此稍有疏忽則會出現(xiàn) NPE 問題
- 如果使用 @Component、@Value、@Autowired 等注解委婉的實(shí)現(xiàn)了注入到靜態(tài)變量中,但其終究還是在 Spring 容器加載之后進(jìn)行加載賦值的,實(shí)際使用仍依賴 Spring 容器環(huán)境
- 如果是單純的 Java 靜態(tài)工具類,則應(yīng)該使用 Properties 類加載文件的方式,這樣才可以完全不依賴 Spring 環(huán)境的運(yùn)行。
到此這篇關(guān)于詳解Spring如何注入靜態(tài)變量的文章就介紹到這了,更多相關(guān)Spring注入靜態(tài)變量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java集合之Set、HashSet、LinkedHashSet和TreeSet深度解析
這篇文章主要介紹了Java集合之Set、HashSet、LinkedHashSet和TreeSet深度解析,List是有序集合的根接口,Set是無序集合的根接口,無序也就意味著元素不重復(fù),更嚴(yán)格地說,Set集合不包含一對元素e1和e2 ,使得e1.equals(e2) ,并且最多一個空元素,需要的朋友可以參考下2023-09-09Spring Boot集成Druid數(shù)據(jù)庫連接池
這篇文章主要介紹了Spring Boot集成Druid數(shù)據(jù)庫連接池,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04SpringBoot之配置logging日志及在控制臺中輸出過程
這篇文章主要介紹了SpringBoot之配置logging日志及在控制臺中輸出過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06mybatis-plus 新增/修改如何實(shí)現(xiàn)自動填充指定字段
這篇文章主要介紹了mybatis-plus 新增/修改實(shí)現(xiàn)自動填充指定字段方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06解決idea 拉取代碼出現(xiàn)的 “ Сannot Run Git Cannot identify version of
這篇文章主要介紹了解決idea 拉取代碼出現(xiàn)的 “ Сannot Run Git Cannot identify version of git executable: no response“的問題,需要的朋友可以參考下2020-08-08SpringCloud連接不上遠(yuǎn)程N(yùn)acos問題排查
本文主要介紹了SpringCloud連接不上遠(yuǎn)程N(yùn)acos問題排查,可能是因?yàn)槲撮_放端口,或集群內(nèi)部通信異常等,下面就來介紹一下問題解決,感興趣的可以了解一下2024-06-06