【问题标题】:Read external .properties file from the install directory (not the current directory)从安装目录(不是当前目录)读取外部 .properties 文件
【发布时间】:2021-12-29 16:07:47
【问题描述】:

我正在使用 Gradle 应用程序插件和“distZip”任务将 Spring Boot 应用程序作为压缩的“bootJar”分发。最终用户将获得 zip 文件,解压缩并运行它,只需键入“myApp”(由插件很好地创建的 shell 脚本)。

我希望最终用户创建一个“myapp.properties”文件(我选择的名称)并将其放在安装目录中,或者安装目录下的“config”目录中。

假设我将嵌入的(在 jar 中)application.properties 文件设置如下:

  • spring.config.import = file:./myapp.properties 只会从当前目录中读取
  • spring.config.import = file:/etc/myapp.properties 将从指定目录读取——但我不知道这是在 构建时间(最终用户在 安装时间确定它)

如何设置我的应用程序,以便 Spring Boot 可以从稍后指定位置的外部文件中读取属性?

注意:我知道我可以使用生成的脚本来传递环境变量或 Spring Boot 属性,但我希望完全在 Spring Boot 中执行此操作,因此我不需要修改生成良好的 shell 脚本。

【问题讨论】:

    标签: java spring spring-boot properties-file


    【解决方案1】:

    spring.config.import = file:./myapp.properties 只会从 当前目录 spring.config.import = file:/etc/myapp.properties 将从指定目录读取——但我不知道这是什么 是在构建时(最终用户在安装时确定)

    为什么要复杂化呢。

    将您希望在构建应用程序时静态配置为默认值的所有属性放入 jar 中。

    嵌入式application.properties

     server.port = 8080
     prop1.element = something
    

    然后客户端可以创建另一个文件application.properties并将它与jar放在同一目录中并定义更多尚未定义的属性。

     prop2.element = something2   
     prop3.element = something3
    

    默认情况下,Spring Boot 会从嵌入文件以及启动期间放置 jar 的当前目录中的文件加载属性。

    在外部application.properties 中,您还可以覆盖嵌入application.properties 中存在的属性。所以如果当前目录下与jar相同的外部文件如下

     prop2.element = something2   
     prop3.element = something3
     prop1.element = something4 <--- this value here will overwrite the value 'something' from embedded file 
    

    根据spring doc

    SpringApplication 将从 application.properties 加载属性 在以下位置创建文件并将它们添加到 Spring 环境:

    1. /config 当前目录的子目录。

    2. 当前目录

    3. 类路径 /config 包

    4. classpath根目录排序

    优先级(在列表中较高位置定义的属性 覆盖在较低位置定义的那些)。

    从 cmets 获得更多意见后,您似乎还面临另一个问题。您从另一个目录的命令行启动应用程序,因此该目录被视为 spring 将查找外部配置的目录,而不是放置 jar 的位置。

    例如,假设 jar 被放置在当前目录中存在的目标文件夹中。使用以下命令启动应用程序:

    java -jar target/demo-0.0.1-SNAPSHOT.jar
    

    但是目标文件夹中存在的外部application.properties 没有从spring 加载,因为您从另一个目录执行了命令。可以通过以下方式启动应用来解决这个问题

    java -jar -Dspring.config.additional-location=./target/ target/demo-0.0.1-SNAPSHOT.jar
    

    这应该不难,因为您已经在命令行中提供了 jar 所在的路径。

    【讨论】:

    • “当前目录”与“放置jar的目录”不同。我想从 jar 目录中读取;除非我告诉它从哪里读取,否则 Spring 不会这样做。用户可以从他们选择的任何目录运行应用程序。
    • @DavidH 来自您的问题:I would like the end-user to create a "myapp.properties" file (a name I chose) and put it in the installation directory, or a "config" directory under the installation directory. 当我们有 Jar 文件时的安装目录意味着 jar 存在的位置。
    • 没错!但是 Spring 不会从那里读取它!它将从当前工作目录中读取它。试试看(我试过了)!
    • @DavidH 所以你的意思是执行命令从另一个文件夹启动 jar,然后成为当前目录。我说的对吗?
    • @DavidH 检查更新的答案,您会找到解决问题的方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 1970-01-01
    相关资源
    最近更新 更多