从 jar 中读取外部配置文件

Posted

技术标签:

【中文标题】从 jar 中读取外部配置文件【英文标题】:Read external configuration file from jar 【发布时间】:2015-11-30 15:49:08 【问题描述】:

我正在构建一个需要读取外部属性文件的 jar(使用 Maven 和 Spring Boot)。它应该在运行 jar 的同一目录中(或在它的相对路径中,如 ./config.properties./conf/config.properties

现在我可以成功读取资源目录中的嵌入式 jar,但如果我尝试从本地目录读取它,InputStream 将是null

我尝试将本地目录 . 添加到类路径中(解压 jar 我可以在 Class-Path 条目中看到它),但没有成功。

这是我尝试过的:

InputStream in = PropertiesLoader.class.getResourceAsStream("config.properties")
InputStream in = PropertiesLoader.class.getResourceAsStream("./config.properties")
InputStream in = PropertiesLoader.class.getClassLoader().getResourceAsStream("./config.properties")
InputStream in = PropertiesLoader.class.getClass().getResourceAsStream("./config.properties")

在我的 pom.xml 中,我有这个条目来将本地目录添加到类路径:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>bla.bla.Main</mainClass>
            </manifest>
            <manifestEntries>
                <Class-Path>.</Class-Path>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

我也尝试了user.dir 属性,但没有成功。

这应该很“简单”,但我很迷茫。

【问题讨论】:

cmiiw,您正在尝试使用您的 jar 从同一目录中读取文件,对吗?如果是,那我猜new FileInputStream("./file_name.txt") 应该足够了吧? 你在 JAR 中使用application.properties 文件吗? JAR 之外的 config.properties 文件是否被覆盖? @kucing_terbang hm.. 我有一个 FileNotFound.. @geo 不,我没有使用 application.properties。应该是一个覆盖,但只是为了看看它是否会起作用,我已经将 jar 中的名称更改为“default.properties”。 【参考方案1】:

Spring Boot 可以以零配置为您完成读取属性文件的所有繁重工作。无需手动读取属性文件。有关详细信息,请参阅文档的this 部分。

为了让你的生活尽可能轻松,我提出以下建议(这实际上是 Spring Boot 默认策略):

src/resources 中有一个application.properties 文件,其中包含所有属性的默认值。 在将运行 jar 的环境中,有一个名为 application.properties 的文件,或者在与 jar 相同的目录中,或者在名为 config 的子目录中。

一旦你这样做了,每个属性将通过@Value注解或@ConfigurationProperties类型处理在Spring Beans中可用。

还请注意,您可以将属性文件命名为 application.properties 以外的名称,只要在运行 jar 时设置 --spring.config.name=config,例如 java -jar somejar.jar --spring.config.name=config

【讨论】:

嗯,谢谢。我已经看过了。我对使用注射来做这样的事情并不感到兴奋,但我会试一试。所以似乎没有办法告诉 Spring Boot 使用不同的文件名(一部分是在运行时告诉他该属性)? 你也可以使用标准的 Spring @PropertySource。但是我建议坚持约定并使用属性注入。它们将使您的生活更轻松,并使应用程序比手动读取属性文件更具可测试性【参考方案2】:

我在下面尝试并成功:

Properties properties = new Properties();
properties.load(new FileInputStream("./test/application.properties"));

或弹簧方式

Properties properties = PropertiesLoaderUtils.loadProperties(new FileSystemResource("./test/application.properties"));

他们都做同样的把戏,第二个是安全的,所以你不需要关闭输入流。

诀窍是,您需要将test 文件夹与src 创建同一级别,以使其与maven 一起使用。所以当你有了 jar 之后,你可以创建 test 文件夹并将文件放入其中。

也作为罐子测试。

【讨论】:

以上是关于从 jar 中读取外部配置文件的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot:加载和读取jar包外面的资源文件

jar读取外部和内部配置文件的问题

Springboot打成JAR包后读取外部配置文件

jar包启动方式以及配置文件读取顺序

Spring Boot配置文件放在jar外部

Spring Boot配置文件放在jar外部