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

posted @ 2018-11-15 10:07  安琪拉的博客(公众号)  阅读(9737)  评论(0编辑  收藏  举报