點擊上方藍色「大數據實戰演練」,選擇「設爲星標」或「置頂」java
回覆「資源」領取獨家整理的學習資料!web
每個成功人士的背後,一定曾經作出過勇敢而又孤獨的決定。spring
放棄不難,但堅持很酷~sql
1、問題描述
今天啓動 spring boot 項目的時候,有時候會報加載不到配置文件的屬性。配置文件的屬性是用 @Value 獲取的,屬性有時候會是 null 。npm
程序通過簡化,是這樣的,有一個 InitConfig 類,用來讓靜態工具類能獲取到配置文件的屬性值。內容是這樣的:c#
在靜態工具類中,經過 InitConfig.load(); 來獲取配置文件中的屬性值,這是沒問題的,由於 @Configuration 類會在 spring 程序啓動過程當中就執行了。後端
但若是在 @Service 修飾的類中,調用 InitConfig.load(); 以下圖所示:服務器
這樣,有時候就會獲取不到配置文件中的屬性值。以下圖所示:微信
很奇怪,通過研究嘗試,終於瞭解了其中的原因。如今給你們分享一下。app
2、spring bean 加載順序
以前我一直覺得 @Configuration 會比 @Service、@Component 優先執行。其實不對。看下面的代碼片斷:
文件結構:
Aaa.java 文件:
Bb.java 文件:
再結合上面的 InitConfig.java 文件。當項目啓動的過程當中,你會發現這樣的結果:
Aaa.java 先執行,Bb.java 其次,InitConfig.java 文件最後執行。這樣就驗證了 @Configuration 並不會比 @Service、@Component 優先執行。
我猜想的應該是,spring 將上面帶有註解的類都放在一塊兒,統一加載。默認是根據 包名+文件名稱 來判斷加載順序的。
@Configuration、@Service、@Component 都會將修飾的類交給 spring 來管理,文件初始化的時候,會加載屬性,無參構造方法等。
3、設置 spring bean 加載順序
有這麼一個註解,@DependsOn,它能夠指定依賴哪一個 bean ,讓本身在該 bean 以後加載。這樣就能夠實現 bean 順序的設置。
@Configuration
@DependsOn({"initConfig", "aaa"})
public class Bb {
...
}
@DependsOn 能夠指定多個 bean ,用 String[] 表示,有順序。@DependsOn({"initConfig", "aaa"}) 表示在執行 Bb.java 以前,會首先執行 InitConfig.java,而後再執行 Aaa.java。bean 名稱默認爲 首字母小寫的文件名。
4、小結
@Configuration、@Service、@Component 都會將修飾的類交給 spring 來管理,但就註解這個層面來講,貌似是沒有加載順序的。默認爲 包名+文件名 來判斷加載順序。
若是須要指定加載順序,可使用 @DependsOn 註解。
文中還用到了 @PostConstruct 註解。它是 jdk 中的一個註解, 被 @PostConstruct 修飾的方法會在服務器加載 Servlet 的時候運行,而且只會被服務器調用一次。
好啦,以上基本就是對 Spring bean 加載順序致使問題 bug 的思考,若是上述描述有欠缺或錯誤,歡迎指正,感謝。
往期推薦
掃一掃,咱們的故事就開始了。
若是這篇文章對你有所啓發,點贊、轉發都是一種支持!
讓我知道你在看
本文分享自微信公衆號 - 大數據實戰演練(gh_f942bfc92d26)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。