Spring Boot 可执行 jar 和外部配置文件

Posted

技术标签:

【中文标题】Spring Boot 可执行 jar 和外部配置文件【英文标题】:Spring Boot executable jar and external configuration file 【发布时间】:2016-04-03 03:17:54 【问题描述】:

我有一个使用 3rd-party jar 的 Spring Boot 应用程序。此 jar 需要一个 xml 配置文件,该文件必须由客户端在运行时(单独)提供,并且不能预先打包。第 3 方库使用以下顺序加载该文件(我剥离了 ifs 和空检查):

    FileConfigurator.class.getResource("/" + filename);
    Thread.currentThread().getContextClassLoader().getResource("/" + filename);
    Thread.currentThread().getContextClassLoader().getResource(filename);

我无法更改 lib 加载文件的方式(例如,使用 Spring 的资源加载),因此它必须位于类路径中。因此我似乎失去了像java -jar my-spring-boot-app.jar 那样执行它的可能性,因为-jar 选项会阻止添加任何额外的类路径条目。所以我开始像

一样运行它

java -classpath my-spring-boot-app.jar:./config/: org.springframework.boot.loader.JarLauncher

我的目录结构如下:

|-- config
|   |-- application.properties
|   `-- 3rd-party-config.xml
|-- my-spring-boot-app.jar

但随后 Spring 的自动装配开始失败:config 目录中的附加 application.properties 文件覆盖了一些设置,使用上述命令会导致应用启动失败:

创建名为“ORBConfig”的 bean 时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 java.lang.String com.company.app.communication.corba.orb.ORBConfig.serverName;嵌套异常是 java.lang.IllegalArgumentException:无法解析字符串值“$application.corba.serverName”中的占位符“application.corba.serverName”

字段String serverName 使用@Value("$application.corba.serverName") 进行注释,该属性在JAR 中捆绑的application.properties 文件中定义,并且当配置目录中不存在额外的application.properties 时,值注入可以正常工作。

我的实际问题是:部署和/或运行 Spring Boot 应用程序的可取方式是什么,以利用可执行 Jar 功能,在运行时提供额外的类路径资源,并且仍然能够覆盖一些(但不是全部)属性通过类路径application.properties 文件?

应用使用spring boot maven插件打包,使用spring-boot-starter-parent父POM。

【问题讨论】:

【参考方案1】:

如果您不更改启动命令,一个简单的答案:

./config/application.properties 移动到./config/config/application.properties

如果存在多个同名的类路径资源,Spring Boot 将仅加载其中一个,在您的情况下,Spring Boot 加载并优先考虑属性资源如下:

    file:config/application.properties classpath:application.properties 可能解析为 my-spring-boot-app.jar!/applcation.properties./config/application.properties

如果您的 classLoader 选择 ./config/application.properties 作为第二个属性源。砰!

Spring Boot 的默认配置属性资源路径优先级(从高到低优先级)为:

    file:config/ file: classpath:config/ classpath

普通的可执行jar执行使这两个配置属性落入:

    file:config/application.properties classpath:application.properties(来自罐子)

./config/application.propertie 移动到 './config/config/application.properties' 变为:

    classpath:config/application.properties classpath:application.properties(来自罐子)

两者顺序相同,没有歧义。

【讨论】:

以上是关于Spring Boot 可执行 jar 和外部配置文件的主要内容,如果未能解决你的问题,请参考以下文章

spring boot打jar包运行,加载jar包外部的页面以及静态资源文件

如何在spring-boot可执行jar文件中配置java logging.properties

如何将外部jar文件传递给spring boot项目? [复制]

Spring Boot 外部化配置简介

Gradle 如何打包 Spring Boot 可执行 JAR

没有可执行jar的Spring Boot 2 Gradle插件