我有多个属性文件,我想从classpath加载。 /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
我将applicationcontext
更改为
<util:properties id="Job2Props"
location="{app.config.location}/job2.properties"></util:properties>
这就是我在加载Application时在文件和类路径之间进行分离的方法。
的编辑:
//psuedo code
if (StringUtils.isBlank(app.config.location)) {
System.setProperty(APP_CONFIG_LOCATION, "classpath:");
}
我真的不想使用上面的解决方法,并且让spring覆盖类路径上的所有外部配置文件,就像它对application.properties
文件一样。
答案 0 :(得分:117)
使用Spring Boot时,属性按以下顺序加载(请参阅Spring Boot参考指南中的Externalized Configuration)。
解析属性时(即@Value("${myprop}")
解析以相反的顺序完成(从9开始)。
要添加不同的文件,您可以使用spring.config.location
属性,该属性采用逗号分隔的属性文件列表或文件位置(目录)。
-Dspring.config.location=your/config/dir/
上面的内容将添加一个目录,将为application.properties
个文件提供参考。
-Dspring.config.location=classpath:job1.properties,classpath:job2.properties
这会将2个属性文件添加到已加载的文件中。
默认配置文件和位置在附加指定的spring.config.location
之前加载,这意味着后者将始终覆盖先前设置的属性。 (另请参阅Spring Boot Reference Guide的this section)。
如果
spring.config.location
包含目录(而不是文件),则它们应以/结尾(并且在加载之前将附加从spring.config.name
生成的名称)。无论classpath:,classpath:/config,file:,file:config/
的值如何,始终使用默认搜索路径spring.config.location
。通过这种方式,您可以在application.properties
(或使用spring.config.name
选择的任何其他基本名称)中为应用程序设置默认值,并在运行时使用不同的文件覆盖它,保留默认值。
更新: 由于spring.config.location的行为现在覆盖默认值而不是添加到默认值。您需要使用spring.config.additional-location来保留默认值。这是从1.x到2.x的行为变化
答案 1 :(得分:27)
使用Spring启动时,spring.config.location可以正常工作,只需提供逗号分隔的属性文件。
请参阅以下代码
@PropertySource(ignoreResourceNotFound=true,value="classpath:jdbc-${spring.profiles.active}.properties")
public class DBConfig{
@Value("${jdbc.host}")
private String jdbcHostName;
}
}
可以将jdbc.properties的默认版本放在应用程序中。可以设置外部版本。
java -jar target/myapp.jar --spring.config.location=classpath:file:///C:/Apps/springtest/jdbc.properties,classpath:file:///C:/Apps/springtest/jdbc-dev.properties
根据使用spring.profiles.active属性设置的配置文件值,将获取jdbc.host的值。 所以当(在Windows上)
set spring.profiles.active=dev
jdbc.host将从jdbc-dev.properties中获取值。
代表
set spring.profiles.active=default
jdbc.host将从jdbc.properties获取值。
答案 2 :(得分:20)
看看PropertyPlaceholderConfigurer,我发现使用它比注释更清晰。
e.g。
@Configuration
public class PropertiesConfiguration {
@Bean
public PropertyPlaceholderConfigurer properties() {
final PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
// ppc.setIgnoreUnresolvablePlaceholders(true);
ppc.setIgnoreResourceNotFound(true);
final List<Resource> resourceLst = new ArrayList<Resource>();
resourceLst.add(new ClassPathResource("myapp_base.properties"));
resourceLst.add(new FileSystemResource("/etc/myapp/overriding.propertie"));
resourceLst.add(new ClassPathResource("myapp_test.properties"));
resourceLst.add(new ClassPathResource("myapp_developer_overrides.properties")); // for Developer debugging.
ppc.setLocations(resourceLst.toArray(new Resource[]{}));
return ppc;
}
答案 3 :(得分:12)
Spring boot 1.X和Spring Boot 2.X对Externalized Configuration
没有提供相同的选项和行为。
M。Deinum的很好回答是关于Spring Boot 1的特殊性。 我将在此处为Spring Boot 2更新。
环境属性的来源和顺序
Spring Boot 2使用一个非常特殊的PropertySource
顺序,该顺序旨在合理地覆盖值。按以下顺序考虑属性:
- 测试中的
Devtools主目录上的全局设置属性 (在devtools处于活动状态时,〜/ .spring-boot-devtools.properties)。
- 测试中的
@TestPropertySource
注释。- 来自
@SpringBootTest#properties
注释属性。命令 行参数。SPRING_APPLICATION_JSON
的属性(嵌入在 环境变量或系统属性)。
ServletConfig
初始化参数。- 来自
ServletContext
初始化参数。java:comp/env
的JNDI属性。
Java系统属性(
System.getProperties()
)。OS环境变量。
- 包装的jar之外的
仅具有随机属性的
RandomValuePropertySource
。*。特定于配置文件的应用程序属性 (
application-{profile}.properties
和YAML变体)。打包在jar中的特定于配置文件的应用程序属性 (
application-{profile}.properties
和YAML变体)。打包的jar之外的应用程序属性 (
application.properties
和YAML变体)。打包在jar中的应用程序属性 (
application.properties
和YAML变体)。@PropertySource
类上的
@Configuration
注释。默认 属性(通过设置指定SpringApplication.setDefaultProperties
。
要指定外部属性文件,您应该对这些选项感兴趣:
包装的jar之外的
特定于配置文件的应用程序属性 (
application-{profile}.properties
和YAML变体)。打包的jar之外的应用程序属性 (
application.properties
和YAML变体)。@PropertySource
类上的
@Configuration
注释。默认 属性(通过设置指定SpringApplication.setDefaultProperties
。
您只能使用这三个选项之一,也可以根据需要将它们组合在一起。
例如,在非常简单的情况下,仅使用特定于配置文件的属性就足够了,但在其他情况下,您可能要同时使用特定于配置文件的属性,默认属性和@PropertySource
。
application.properties文件的默认位置
关于application.properties
文件(和变体),默认情况下,Spring会按以下顺序加载它们并在环境中添加它们的属性:
当前目录的/ config子目录
当前目录
类路径/ config包
类路径根
从字面上看,更高的优先级是这样的:
classpath:/,classpath:/config/,file:./,file:./config/
。
如何使用具有特定名称的属性文件?
默认位置并不总是足够的:默认位置,例如默认文件名(application.properties
)可能不适合。此外,如在OP问题中一样,您可能需要指定多个配置文件,而不是application.properties
(和变体)。
因此spring.config.name
是不够的。
在这种情况下,您应该使用spring.config.location
环境属性(目录位置或文件路径的逗号分隔列表)来提供显式位置。
要放心使用文件名模式,请优先选择文件路径列表而不是目录列表。
例如,这样做:
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
那是指定文件夹最冗长的方法,也是指定我们的配置文件并清楚地记录有效使用的属性的方法。
spring.config.location现在替换默认位置,而不是添加到默认位置
在Spring Boot 1中,spring.config.location
参数在Spring环境中添加了指定的位置。
但是从Spring Boot 2开始,spring.config.location
将Spring使用的默认位置替换为in the documentation中所述的Spring环境中的指定位置。
使用来配置自定义配置位置时
spring.config.location
,它们将替换默认位置。对于 例如,如果spring.config.location
配置了值classpath:/custom-config/
,file:./custom-config/
,搜索顺序 变为以下内容:
file:./custom-config/
classpath:custom-config/
spring.config.location
现在是确保必须明确指定任何application.properties
文件的一种方法。
对于不应该打包application.properties
文件的超级JAR,这很好。
要在使用Spring Boot 2时保持spring.config.location
的旧行为,可以使用新的spring.config.additional-location
属性而不是spring.config.location
属性,该属性仍会添加位置as stated by the documentation:>
或者,当使用来配置自定义配置位置时
spring.config.additional-location
,除了 默认位置。
实践
因此,假设像在OP问题中一样,您有2个要指定的外部属性文件和uber jar中包含的1个属性文件。
仅使用您指定的配置文件:
-Dspring.config.location=classpath:/job1.properties,classpath:/job2.properties,classpath:/applications.properties
要将配置文件添加到默认位置:
-Dspring.config.additional-location=classpath:/job1.properties,classpath:/job2.properties
在最后一个示例中,不需要 classpath:/applications.properties
,因为默认位置具有默认位置,并且默认位置不会被覆盖,而是扩展。
答案 4 :(得分:6)
我遇到了同样的问题。我希望能够在启动时使用外部文件覆盖内部配置文件,类似于Spring Boot application.properties检测。 就我而言,它是一个user.properties文件,用于存储我的应用程序用户。
我的要求:
从以下位置加载文件(按此顺序)
我提出了以下解决方案:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.util.Properties;
import static java.util.Arrays.stream;
@Configuration
public class PropertiesConfig {
private static final Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);
private final static String PROPERTIES_FILENAME = "user.properties";
@Value("${properties.location:}")
private String propertiesLocation;
@Bean
Properties userProperties() throws IOException {
final Resource[] possiblePropertiesResources = {
new ClassPathResource(PROPERTIES_FILENAME),
new PathResource("config/" + PROPERTIES_FILENAME),
new PathResource(PROPERTIES_FILENAME),
new PathResource(getCustomPath())
};
// Find the last existing properties location to emulate spring boot application.properties discovery
final Resource propertiesResource = stream(possiblePropertiesResources)
.filter(Resource::exists)
.reduce((previous, current) -> current)
.get();
final Properties userProperties = new Properties();
userProperties.load(propertiesResource.getInputStream());
LOG.info("Using {} as user resource", propertiesResource);
return userProperties;
}
private String getCustomPath() {
return propertiesLocation.endsWith(".properties") ? propertiesLocation : propertiesLocation + PROPERTIES_FILENAME;
}
}
现在,应用程序使用类路径资源,但也检查其他给定位置的资源。将挑选和使用存在的最后一个资源。 我可以使用java -jar myapp.jar --properties.location = / directory / myproperties.properties启动我的应用程序,以使用浮动我的船的属性位置。
此处的一个重要细节:使用空字符串作为@Value注释中properties.location的默认值,以避免在未设置属性时出错。
properties.location的约定是:使用目录或属性文件的路径作为properties.location。
如果只想覆盖特定属性,可以使用setIgnoreResourceNotFound(true)的PropertiesFactoryBean将资源数组设置为位置。
我确信此解决方案可以扩展为处理多个文件...
修改强>
这里是我对多个文件的解决方案:)和以前一样,这可以和一个PropertiesFactoryBean结合使用。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toMap;
@Configuration
class PropertiesConfig {
private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);
private final static String[] PROPERTIES_FILENAMES = {"job1.properties", "job2.properties", "job3.properties"};
@Value("${properties.location:}")
private String propertiesLocation;
@Bean
Map<String, Properties> myProperties() {
return stream(PROPERTIES_FILENAMES)
.collect(toMap(filename -> filename, this::loadProperties));
}
private Properties loadProperties(final String filename) {
final Resource[] possiblePropertiesResources = {
new ClassPathResource(filename),
new PathResource("config/" + filename),
new PathResource(filename),
new PathResource(getCustomPath(filename))
};
final Resource resource = stream(possiblePropertiesResources)
.filter(Resource::exists)
.reduce((previous, current) -> current)
.get();
final Properties properties = new Properties();
try {
properties.load(resource.getInputStream());
} catch(final IOException exception) {
throw new RuntimeException(exception);
}
LOG.info("Using {} as user resource", resource);
return properties;
}
private String getCustomPath(final String filename) {
return propertiesLocation.endsWith(".properties") ? propertiesLocation : propertiesLocation + filename;
}
}
答案 5 :(得分:6)
这是一种使用弹簧启动的简单方法
<强> TestClass.java 强>
@Configuration
@Profile("one")
@PropertySource("file:/{selected location}/app.properties")
public class TestClass {
@Autowired
Environment env;
@Bean
public boolean test() {
System.out.println(env.getProperty("test.one"));
return true;
}
}
app.properties 上下文,位于所选位置
test.one = 1234
您的春季启动应用
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(testApplication.class, args);
}
}
和预定义的 application.properties 上下文
spring.profiles.active = one
您可以根据需要编写任意数量的配置类,只需设置 spring.profiles.active =配置文件名称/名称{以逗号分隔}
即可启用/禁用它们你可以看到弹簧靴很棒,只需要一段时间熟悉,值得一提的是你也可以在你的领域使用@Value
@Value("${test.one}")
String str;
答案 6 :(得分:6)
spring boot允许我们为不同的环境编写不同的配置文件,例如我们可以为生产,qa和本地环境提供单独的属性文件
application-local.properties文件,其中包含根据我本地计算机的配置
spring.profiles.active=local
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=users
spring.data.mongodb.username=humble_freak
spring.data.mongodb.password=freakone
spring.rabbitmq.host=localhost
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.port=5672
rabbitmq.publish=true
同样,我们可以根据需要编写application-prod.properties和application-qa.properties多个属性文件
然后编写一些脚本来启动不同环境的应用程序,例如
mvn spring-boot:run -Drun.profiles=local
mvn spring-boot:run -Drun.profiles=qa
mvn spring-boot:run -Drun.profiles=prod
答案 7 :(得分:5)
我刚刚遇到了类似的问题,最终找出了原因:application.properties文件的所有权和rwx属性有误。因此,当tomcat启动时,application.properties文件位于正确的位置,但由另一个用户拥有:
$ chmod 766 application.properties
$ chown tomcat application.properties
答案 8 :(得分:0)
我发现这是一个有用的模式:
@RunWith(SpringRunner)
@SpringBootTest(classes = [ TestConfiguration, MyApplication ],
properties = [
"spring.config.name=application-MyTest_LowerImportance,application-MyTest_MostImportant"
,"debug=true", "trace=true"
]
)
这里我们覆盖&#34; application.yml&#34;的使用。使用&#34; application-MyTest_LowerImportance.yml&#34;还有&#34; application-MyTest_MostImportant.yml&#34;
(Spring也会查找.properties文件)
还包括作为额外奖励的调试和跟踪设置,在单独的行上,以便您可以在需要时将其注释掉;]
调试/跟踪非常有用,因为Spring会转储它加载的所有文件的名称以及它尝试加载的文件的名称。
您将在运行时在控制台中看到这样的行:
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./config/application-MyTest_MostImportant.properties' (file:./config/application-MyTest_MostImportant.properties) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./config/application-MyTest_MostImportant.xml' (file:./config/application-MyTest_MostImportant.xml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./config/application-MyTest_MostImportant.yml' (file:./config/application-MyTest_MostImportant.yml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./config/application-MyTest_MostImportant.yaml' (file:./config/application-MyTest_MostImportant.yaml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./config/application-MyTest_LowerImportance.properties' (file:./config/application-MyTest_LowerImportance.properties) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./config/application-MyTest_LowerImportance.xml' (file:./config/application-MyTest_LowerImportance.xml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./config/application-MyTest_LowerImportance.yml' (file:./config/application-MyTest_LowerImportance.yml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./config/application-MyTest_LowerImportance.yaml' (file:./config/application-MyTest_LowerImportance.yaml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./application-MyTest_MostImportant.properties' (file:./application-MyTest_MostImportant.properties) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./application-MyTest_MostImportant.xml' (file:./application-MyTest_MostImportant.xml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./application-MyTest_MostImportant.yml' (file:./application-MyTest_MostImportant.yml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./application-MyTest_MostImportant.yaml' (file:./application-MyTest_MostImportant.yaml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./application-MyTest_LowerImportance.properties' (file:./application-MyTest_LowerImportance.properties) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./application-MyTest_LowerImportance.xml' (file:./application-MyTest_LowerImportance.xml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./application-MyTest_LowerImportance.yml' (file:./application-MyTest_LowerImportance.yml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./application-MyTest_LowerImportance.yaml' (file:./application-MyTest_LowerImportance.yaml) resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/config/application-MyTest_MostImportant.properties' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/config/application-MyTest_MostImportant.xml' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/config/application-MyTest_MostImportant.yml' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/config/application-MyTest_MostImportant.yaml' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.properties' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.xml' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.yml' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.yaml' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/application-MyTest_MostImportant.properties' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/application-MyTest_MostImportant.xml' resource not found
DEBUG 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Loaded config file 'file:/Users/xxx/dev/myproject/target/test-classes/application-MyTest_MostImportant.yml' (classpath:/application-MyTest_MostImportant.yml)
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/application-MyTest_MostImportant.yaml' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/application-MyTest_LowerImportance.properties' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/application-MyTest_LowerImportance.xml' resource not found
DEBUG 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Loaded config file 'file:/Users/xxx/dev/myproject/target/test-classes/application-MyTest_LowerImportance.yml' (classpath:/application-MyTest_LowerImportance.yml)
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'classpath:/application-MyTest_LowerImportance.yaml' resource not found
TRACE 93941 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped config file 'file:./config/application-MyTest_MostImportant-test.properties' (file:./config/application-MyTest_MostImportant-test.properties) resource not found
答案 9 :(得分:0)
@mxsb解决方案的修改版,允许我们定义多个文件,在我的情况下,这些文件是yml文件。
在我的application-dev.yml文件中,我添加了此配置,该配置文件允许我注入所有带有-dev.yml文件的yml。这也可以是特定文件的列表。 “ classpath:/test/test.yml,classpath:/test2/test.yml”
application:
properties:
locations: "classpath*:/**/*-dev.yml"
这有助于获取属性图。
@Configuration
public class PropertiesConfig {
private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);
@Value("${application.properties.locations}")
private String[] locations;
@Autowired
private ResourceLoader rl;
@Bean
Map<String, Properties> myProperties() {
return stream(locations)
.collect(toMap(filename -> filename, this::loadProperties));
}
private Properties loadProperties(final String filename) {
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
try {
final Resource[] possiblePropertiesResources = ResourcePatternUtils.getResourcePatternResolver(rl).getResources(filename);
final Properties properties = new Properties();
stream(possiblePropertiesResources)
.filter(Resource::exists)
.map(resource1 -> {
try {
return loader.load(resource1.getFilename(), resource1);
} catch (IOException e) {
throw new RuntimeException(e);
}
}).flatMap(l -> l.stream())
.forEach(propertySource -> {
Map source = ((MapPropertySource) propertySource).getSource();
properties.putAll(source);
});
return properties;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
但是,如果像我这样,我想必须为每个概要文件分割yml文件并加载它们,然后在初始化bean之前将其直接注入spring配置。
config
- application.yml
- application-dev.yml
- application-prod.yml
management
- management-dev.yml
- management-prod.yml
...你明白了
组件略有不同
@Component
public class PropertiesConfigurer extends PropertySourcesPlaceholderConfigurer
implements EnvironmentAware, InitializingBean {
private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfigurer.class);
private String[] locations;
@Autowired
private ResourceLoader rl;
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
// save off Environment for later use
this.environment = environment;
super.setEnvironment(environment);
}
@Override
public void afterPropertiesSet() throws Exception {
// Copy property sources to Environment
MutablePropertySources envPropSources = ((ConfigurableEnvironment) environment).getPropertySources();
envPropSources.forEach(propertySource -> {
if (propertySource.containsProperty("application.properties.locations")) {
locations = ((String) propertySource.getProperty("application.properties.locations")).split(",");
stream(locations).forEach(filename -> loadProperties(filename).forEach(source ->{
envPropSources.addFirst(source);
}));
}
});
}
private List<PropertySource> loadProperties(final String filename) {
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
try {
final Resource[] possiblePropertiesResources = ResourcePatternUtils.getResourcePatternResolver(rl).getResources(filename);
final Properties properties = new Properties();
return stream(possiblePropertiesResources)
.filter(Resource::exists)
.map(resource1 -> {
try {
return loader.load(resource1.getFilename(), resource1);
} catch (IOException e) {
throw new RuntimeException(e);
}
}).flatMap(l -> l.stream())
.collect(Collectors.toList());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
答案 10 :(得分:0)
如果要覆盖application.properties文件中指定的值,则可以在运行应用程序时更改活动配置文件,并为该配置文件创建应用程序属性文件。因此,例如,让我们指定活动配置文件“ override”,然后,假设您已经在/ tmp下创建了名为“ application-override.properties”的新应用程序属性文件,那么您可以运行
java -jar yourApp.jar --spring.profiles.active="override" --spring.config.location="file:/tmp/,classpath:/"
spring.config.location下指定的值以相反顺序求值。因此,在我的示例中,首先评估classpat,然后评估文件值。
如果jar文件和“ application-override.properties”文件位于当前目录中,则您实际上可以简单地使用
java -jar yourApp.jar --spring.profiles.active="override"
因为Spring Boot会为您找到属性文件
答案 11 :(得分:-1)
试图解决这个问题时,我遇到了很多问题。这是我的设置,
Dev Env:Windows 10, Java:1.8.0_25, 春季靴:2.0.3.RELEASE, 春季:5.0.7。发布
我发现Spring坚持了“合理的配置默认值”概念。这就是说,您必须将所有属性文件作为war文件的一部分。进入该目录后,您可以使用“ --spring.config.additional-location”命令行属性覆盖它们,以指向外部属性文件。但是,如果属性文件不是原始war文件的一部分,则将无法使用。
演示代码: https://github.com/gselvara/spring-boot-property-demo/tree/master