我有多个属性文件,我想从类路径加载 . /src/main/resources
下有一个默认设置,它是 myapp.jar
的一部分 . 我的 springcontext
期望文件在类路径上 . 即
<util:properties id="Job1Props"
location="classpath:job1.properties"></util:properties>
<util:properties id="Job2Props"
location="classpath:job2.properties"></util:properties>
我还需要使用外部集覆盖这些属性的选项 . 我在 cwd
中有一个外部配置文件夹 . 根据spring boot doc配置文件夹应该在classpath上 . 但是从文档中不清楚它是否只会覆盖 applicaiton.properties
或者配置中的所有属性 .
当我测试它时,只有 application.properties
被拾取,其余的属性仍然从 /src/main/resources
中获取 . 我已经尝试将它们作为逗号分隔列表提供给 spring.config.location
但是默认设置仍未被覆盖 .
如何使多个外部配置文件覆盖默认配置文件?
作为解决方法,我目前使用 app.config.location
(app特定属性),我通过命令行提供 . 即
java -jar myapp.jar app.config.location=file:./config
我把_396200改为了
<util:properties id="Job2Props"
location="{app.config.location}/job2.properties"></util:properties>
这就是我在加载Application时在文件和类路径之间进行分离的方法 .
EDITS:
//psuedo code
if (StringUtils.isBlank(app.config.location)) {
System.setProperty(APP_CONFIG_LOCATION, "classpath:");
}
我真的不想使用上面的解决方法,并让spring覆盖类路径上的所有外部配置文件,就像它对 application.properties
文件一样 .
12 回答
如果要覆盖application.properties文件中指定的值,则可以在运行应用程序时更改活动配置文件,并为配置文件创建应用程序属性文件 . 因此,例如,让我们指定活动配置文件“覆盖”然后,假设您已在/ tmp下创建了名为“application-override.properties”的新应用程序属性文件,那么您可以运行
spring.config.location下指定的值以相反的顺序计算 . 因此,在我的示例中,首先计算classpat,然后计算文件值 .
如果jar文件和“application-override.properties”文件在当前目录中,您实际上可以简单地使用
因为Spring Boot会为你找到属性文件
我有同样的问题 . 我希望能够在启动时使用外部文件覆盖内部配置文件,类似于Spring Boot application.properties检测 . 在我的例子中,它是一个user.properties文件,用于存储我的应用程序用户 .
我的要求:
从以下位置加载文件(按此顺序)
类路径
当前目录的A / config子目录 .
当前目录
从启动时命令行参数给出的目录或文件位置
我提出了以下解决方案:
现在,应用程序使用类路径资源,但也检查其他给定位置的资源 . 将挑选和使用存在的最后一个资源 . 我可以使用java -jar myapp.jar --properties.location = / directory / myproperties.properties启动我的应用程序,以使用浮动我的船的属性位置 .
这里有一个重要的细节:使用空字符串作为@Value注释中properties.location的默认值,以避免在未设置属性时出错 .
properties.location的约定是:使用属性文件的目录或路径作为properties.location .
如果要仅覆盖特定属性,则可以将具有setIgnoreResourceNotFound(true)的PropertiesFactoryBean与资源数组设置为位置一起使用 .
我确信这个解决方案可以扩展到处理多个文件......
EDIT
这里我的多个文件的解决方案:)像以前一样,这可以与PropertiesFactoryBean结合使用 .
看看PropertyPlaceholderConfigurer,我发现使用它比注释更清晰 .
例如
这是一种使用 spring 靴的简单方法
TestClass.java
app.properties 上下文,位于您选择的位置
你的 spring boot application
和预定义的 application.properties 上下文
您可以根据需要编写任意数量的配置类,并通过设置spring.profiles.active =配置文件名称/名称{以逗号分隔}来启用/禁用它们
你可以看到 spring 靴很棒,只需要一段时间熟悉,值得一提的是你也可以在你的领域使用@Value
使用Spring引导,spring.config.location确实有效,只需提供逗号分隔的属性文件 .
看下面的代码
可以将jdbc.properties的默认版本放在应用程序中 . 可以设置外部版本 .
根据使用spring.profiles.active属性设置的配置文件值,将获取jdbc.host的值 . 所以当(在Windows上)
jdbc.host将从jdbc-dev.properties获取值 .
对于
jdbc.host将从jdbc.properties获取值 .
Spring引导1.X和Spring Boot 2.X不提供有关Externalized Configuration的相同选项和行为 .
M. Deinum的非常好的答案是指Spring引导1特性 .
I will update for Spring Boot 2 here.
Environment properties sources and order
Spring Boot 2使用了一个非常特殊的
PropertySource
命令,旨在允许合理地覆盖值 . 按以下顺序考虑属性:要指定外部属性文件,您应该对以下选项感兴趣:
您只能使用这3个选项中的一个,或根据您的要求进行组合 .
例如,对于非常简单的情况,仅使用特定于配置文件的属性就足够了,但在其他情况下,您可能希望同时使用特定于配置文件的属性,默认属性和
@PropertySource
.Default locations for application.properties files
关于
application.properties
文件(和变体),默认情况下,Spring按以下顺序加载它们并在环境中添加它们的属性:更高的优先级是如此字面意思:
classpath:/,classpath:/config/,file:./,file:./config/
.How to use properties files with specific names ?
默认位置并不总是足够:默认文件名(
application.properties
)等默认位置可能不合适 . 此外,如在OP问题中,您可能需要指定除application.properties
(和变体)之外的多个配置文件 .所以
spring.config.name
还不够 .在这种情况下,您应该使用
spring.config.location
环境属性(它是以逗号分隔的目录位置或文件路径列表)提供显式位置 .关于文件名模式的自由是有利于目录列表上的文件路径列表 .
比如这样做:
这种方式最简单,只是指定文件夹,但它也是非常精细地指定我们的配置文件并清楚地记录有效使用的属性的方法 .
spring.config.location now replaces default locations instead of adding to them
使用Spring Boot 1,
spring.config.location
参数在Spring环境中添加指定的位置 .但是从Spring Boot 2开始,
spring.config.location
将Spring使用的默认位置替换为Spring环境中指定的位置in the documentation .spring.config.location
现在是一种确保必须明确指定任何application.properties
文件的方法 .对于不应该打包
application.properties
文件的超级JAR,这是相当不错的 .要在使用Spring Boot 2时保持
spring.config.location
的旧行为,您可以使用新的spring.config.additional-location
属性而不是仍然添加as stated by the documentation位置的spring.config.location
:In practice
因此,假设在OP问题中,您有2个外部属性文件要指定,并且1个属性文件包含在超级jar中 .
要仅使用您指定的配置文件:
要在默认位置向这些文件添加配置文件:
classpath:/applications.properties
在最后一个示例中不是必需的,因为默认位置具有该值,并且默认位置在此不会被覆盖但是已扩展 .@mxsb解决方案的修改版本,允许我们定义多个文件,在我的例子中,这些是yml文件 .
在我的application-dev.yml中,我添加了这个配置,允许我注入所有包含-dev.yml的yml . 这也可以是特定文件的列表 . “类路径:/test/test.yml,classpath:/test2/test.yml”
这有助于获取属性映射 .
但是,如果在我的情况下,我想要为每个配置文件拆分yml文件并加载它们并在bean初始化之前将其直接注入spring配置 .
......你明白了
该组件略有不同
}
使用Spring Boot时,属性按以下顺序加载(请参阅Spring Boot参考指南中的Externalized Configuration) .
命令行参数 .
Java系统属性(System.getProperties()) .
OS环境变量 .
来自java:comp / env的JNDI属性
一个只有随机属性的RandomValuePropertySource . * .
打包jar之外的应用程序属性(application.properties包括YAML和配置文件变体) .
在jar中打包的应用程序属性(application.properties包括YAML和配置文件变体) .
@Configuration类上的
@PropertySource注释 .
默认属性(使用SpringApplication.setDefaultProperties指定) .
解析属性时(即
@Value("${myprop}")
解析以相反的顺序完成(因此从9开始) .要添加不同的文件,您可以使用
spring.config.location
属性,该属性采用逗号分隔的属性文件列表或文件位置(目录) .上面的那个将添加一个目录,将查询
application.properties
文件 .这会将2个属性文件添加到已加载的文件中 .
默认配置文件和位置在附加指定的
spring.config.location
之前加载,这意味着后者将始终覆盖先前设置的属性 . (另请参阅Spring Boot Reference Guide的this section) .我发现这是一个有用的模式:
这里我们覆盖使用"application.yml"来使用"application-MyTest_LowerImportance.yml"以及"application-MyTest_MostImportant.yml"
(Spring也会查找.properties文件)
另外还包括调试和跟踪设置,在单独的行上,以便您可以在需要时将其注释掉;]
调试/跟踪非常有用,因为Spring将转储它加载的所有文件的名称以及它尝试加载的文件的名称 .
您将在运行时在控制台中看到这样的行:
spring boot允许我们为不同的环境编写不同的配置文件,例如我们可以为 生产环境 ,qa和本地环境提供单独的属性文件
application-local.properties文件,根据我的本地机器进行配置
同样,我们可以根据需要编写application-prod.properties和application-qa.properties多个属性文件
然后编写一些脚本来启动不同环境的应用程序,例如
我刚刚遇到了类似的问题,最终找出了原因:application.properties文件具有错误的所有权和rwx属性 . 因此,当tomcat启动时,application.properties文件位于正确的位置,但由另一个用户拥有:
我试图解决这个问题时遇到了很多问题 . 这是我的设置,
Dev Env:Windows 10,Java:1.8.0_25,Spring Boot:2.0.3.RELEASE,Spring:5.0.7.RELEASE
我发现spring是坚持“Sensible defaults for configuration”的概念 . 这意味着,您必须将所有属性文件作为war文件的一部分 . 进入后,您可以使用“--spring.config.additional-location”命令行属性覆盖它们以指向外部属性文件 . 但是如果属性文件不是原始war文件的一部分,这将不起作用 .
演示代码:https://github.com/gselvara/spring-boot-property-demo/tree/master