您的位置:常州熱線首頁 > 汽車 > 正文

内蒙古11选5:拒絕FileNotFoundException!幾個讀取jar包外配置文件的知識點

前言

内蒙古11选5 www.gafob.com 相信很多人遇到過這個問題:本地運行的好好的程序,怎么部署到線上就報找不到配置呢?

初識getResource


案例一
  FieldMapConfig.class.getResource("p1.properties").getPath();
    - 這段代碼在本地運行沒有任何問題,一放到線上就報空指針。
案例二

  • 讀取配置,報錯FileNotFoundException。
  • 乍一看,兩段代碼好像沒有什么區別,但是細心的你,應該發現:
App.class.getClassLoader().getResource("p1.properties").getPath();FieldMapConfig.class.getResource("p1.properties")
  • 一個使用當前class的api,一個使用的當前class的classLoader的api來獲取的,這有什么區別呢?請聽我細細分說。
Class和ClassLoader


  • 秉著探索的態度,我寫了一個例子,請看:
  public static void main( String[] args ) {        if (args.length != 1) {            System.out.println("usage: java -jar com.hyq.simple-1.0.jar args");            return;        }        System.out.println("App.class.getResource(args[0]):");        System.out.println(App.class.getResource(args[0]));        System.out.println();        System.out.println("App.class.getClassLoader().getResource(args[0]):");        System.out.println(App.class.getClassLoader().getResource(args[0]));        System.out.println();        System.out.println("App.class.getResourceAsStream(args[0]):");        System.out.println(App.class.getResourceAsStream(args[0]));        System.out.println();        System.out.println("App.class.getClassLoader().getResourceAsStream(args[0]):");        System.out.println(App.class.getClassLoader().getResourceAsStream(args[0]));        System.out.println();    }


  • 驗證如下:

  • 從上圖可以看出,使用當前類的GetResource和當前類的classloader的getResource,
    獲取到的配置有區別。怎么解釋呢?

前者是讀取的當前類的包目錄下的配置文件

后者讀取的是,jar包內部,根目錄的配置文件。

總結:當讀取配置的路徑不是以/開頭時,會按相對路徑讀取,相對的是當前類的class 這個文件,而采用class的classLoader則是相對于根路徑(也就是我們說的classpath)。


各種路徑試驗


  • 如果你還在為相對路徑,配置文件前面帶不帶/,等一系列問題折騰,那不如動手做做試驗看看,代碼還是上面那段代碼,通過動態傳入配置文件的路徑來讀取,試驗結果如下:

為什么推薦使用getResourceAsStream?


  • 形如:"jar:file:/data/simpleJava/com.hyq.simple-1.0.jar
    !/p1.properties" 這樣的路徑,getResource是無法讀取的,因為他不是一個文件路徑。
    而getResourceAsStream會以流的方式,打開文件來讀取數據,上圖的文件樹,就是我用unzip命令解壓jar包后顯示出來的。
springboot加載配置

默認情況下,springboot會加載名為application的properties或者yml文件。其中查找的順序為:

  • 1、當前jar包所在目錄的config目錄下。
  • 2、當前目錄。
  • 3、jar包內classpath的config目錄。
  • 4、jar包內classpath目錄。

注意:重復定義的配置,會被后者覆蓋。

通過名字動態加載配置?


知識點一
  • boot配置的語法是,凡是以--開頭(兩個橫線)的配置,會被解析。
    相信大家可能遇到過這樣一個場景,同一個jar包要啟動多次,每個進程的配置不一樣,端口不同。

知識點二

通過--spring.config.name 指定配置文件名即可?;褂幸恢中縷嫻姆絞?,直接通過spring.application.json傳遞json,案例如下:

java -Dspring.application.json='{"name":"test"}' -jar myapp.jar


知識點三

當然,你也可以指定多個配置文件,方式如下:

java -jar myproject.jar --spring.config.location=classpath:/p1.properties,classpath:/p2.properties

值得注意的是,config配置文件搜索的順序和指定的順序是剛好相反的。

知識點四

通過spring.profiles.active屬性可以指定那個環境下的配置。

這里我比較喜歡定義兩個yml,然后在application.yml中指定對應環境的配置。

spring:  profiles:    active: prod
知識點五

可以通過@value注解來獲取變量值

@Value("${app.init.welcome-msg:俠夢的開發筆記}")private String msg;

也可以通過@ConfigurationProperties("app.init")注解,放在類來獲取整個配置。


總結
  • 本章節我們做了實驗,了解了getResource和getResourceAsStream的區別。
  • 學習了springboot通過動態指定配置名,讀取配置。
  • 指定讀取多個配置文件。
  • 不同運行環境獲取不同配置的方式。

歡迎來公眾號【俠夢的開發筆記】 一起交流進步

來源:

推薦閱讀:小米手環3隱藏功能
{ganrao}