Spring Boot獲取jar包內資源文件


在Spring Boot多模塊項目中,A模塊是主模塊,依賴B模塊,如下圖1所示,

在對A模塊做打包操作之后 A.jar包可以通過 java -jar -Dspring.profiles.active=dev A.jar 運行,

對A模版的jar文件A.jar解壓之后,會看到如下圖所示的文件結構,B模塊會作為A模塊的依賴模塊放在lib目錄下,當然,其他B模塊所依賴的jar都在這個目錄。

對B模塊的jar文件B.jar解壓,那B模塊編譯前的配置文件resources目錄的內容也在自己jar包內,如下圖2。

                                                            圖1 

               圖2

在IDEA項目中(未打成jar包),可以直接通過getResource拿到資源文件路徑,然后通過File file = new File(path) 加載文件

String path = BohaiQueryProvider.class.getClassLoader().getResource(keyFilePath).getPath()
public URL getResource(String name) {
        URL url;
        if (parent != null) {
            url = parent.getResource(name);
        } else {
            url = getBootstrapResource(name);
        }
        if (url == null) {
            url = findResource(name);
        }
        return url;
    }

但是打成jar包之后,不能通過這種方式獲取依賴jar包的文件了,File文件加載路徑內文件會找不到,那怎樣做呢?

InputStream inputStream = BohaiQueryProvider.class.getResourceAsStream(keyFilePath) byte[] prifileContent = IOUtils.toByteArray(inputStream)

通過 getResourceAsStream方式拿到資源文件,其實 getResourceAsStream函數也是先通過 getResource拿到資源的URL,然后通過流的形式拿到文件

public InputStream getResourceAsStream(String name) {
        URL url = getResource(name);
        try {
            return url != null ? url.openStream() : null;
        } catch (IOException e) {
            return null;
        }
}

附上stackoverflow上的一個問題 https://stackoverflow.com/questions/2815404/load-properties-file-in-jar

問題大致是

getSystemResourceAsStream這個函數在單元測試和Eclipse中運行可以,但是打成jar包作為被別的包依賴的jar出現問題

原因是 getSystemResourceAsStream 在web項目中是會去你的系統classpath加載資源,例如你配置的jdk目錄,而web項目 servlet容器,例如tomcat會將應用的classpath和系統的做區分,最簡單的加載資源的方式是直接用資源所在jar包里的類加載器加載

MyClass.class.getResourceAsStream("/someProps.properties")

另外二個小知識點

The following rules cover about 95% of the decisions that application developers and deployers must make about where to place class and resource files to make them available to web applications:

  • For classes and resources specific to a particular web application, place unpacked classes and resources under /WEB-INF/classes of your web application archive, or place JAR files containing those classes and resources under /WEB-INF/lib of your web application archive.
  • For classes and resources that must be shared across all web applications, place unpacked classes and resources under $CATALINA_BASE/shared/classes, or place JAR files containing those classes and resources under $CATALINA_BASE/shared/lib.

對於web應用,應該將資源文件和類放在/WEB-INF/classes中,對於多個web應用公用的類,放置在$CATALINA_BASE/shared/classes中。

Maven啟動指定Profile通過-P,如mvn spring-boot:run -Ptest,但這是Maven的Profile。

如果要指定spring-boot的spring.profiles.active,spring-boot 1.x 使用mvn spring-boot:run -Drun.profiles=test,spring-boot 2.x 使用mvn spring-boot:run -Dspring-boot.run.profiles=test。參考資料:https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/maven-plugin/examples/run-profiles.html

如果使用命令行直接運行jar文件,則使用java -jar -Dspring.profiles.active=test demo-0.0.1-SNAPSHOT.jar

如果使用開發工具,運行Application.java文件啟動,則增加參數--spring.profiles.active=test


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM