我正在开发一个Spring Web应用程序,我需要在其中拥有变量,它们在本地环境和生产环境中的其他价值中具有不同的价值。
For Eg(文件上传目录)。我的文件上传目录对于本地和prod环境是不同的。
目前我通过检查主机名(如果' localhost'然后是A其他B)并采用这种方法来做到这一点。有另一种方法可以通过属性文件来解决这个问题,有人提供了如何处理这个问题的指示吗?
答案 0 :(得分:20)
您可以根据当前弹簧配置文件或配置文件加载属性。要设置弹簧配置文件,我主要将名为spring.profiles.active
的系统属性设置为所需的值,例如development
或production
。
这个概念非常简单。从系统属性中读取当前活动的配置文件。构建文件名并使用PropertySourcesPlaceholderConfigurer
加载属性文件。使用PropertySourcesPlaceholderConfigurer
可以更轻松地通过@Value
注释访问这些属性。请注意,此示例假定一个配置文件处于活动状当多个配置文件处于活动状态时,可能需要额外注意。
基于Java的配置
@Configuration
public class MyApplicationConfiguration {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
String activeProfile = System.getProperty("spring.profiles.active", "production");
String propertiesFilename = "app-" + activeProfile + ".properties";
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocation(new ClassPathResource(propertiesFilename));
return configurer;
}
}
您还可以导入多个使用@Profile
注释的配置类。 Spring将根据当前活动的配置文件选择要使用的配置。每个类都可以将它自己的PropertySourcesPlaceholderConfigurer
版本添加到应用程序上下文中。
@Configuration
@Import({Development.class, Production.class})
public class MyApplicationConfiguration {}
@Configuration
@Profile("development")
public class Development {}
@Configuration
@Profile // The default
public class Production {}
正如Emerson Farrugia在评论中所说,@Profile
每班级方法对于选择PropertySourcesPlaceholderConfigurer
来说有点激烈。注释@Bean
声明会简单得多。
@Configuration
public class MyApplicationConfiguration {
@Bean
@Profile("development")
public static PropertySourcesPlaceholderConfigurer developmentPropertyPlaceholderConfigurer() {
// instantiate and return configurer...
}
@Bean
@Profile // The default
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
// instantiate and return configurer...
}
}
答案 1 :(得分:7)
一个完全不涉及Spring Profiles的解决方案是使用以下内容:
<context:property-placeholder location="classpath*:config.properties,file:/path/config/config.properties"
ignore-unresolvable="false" ignore-resource-not-found="true"/>
这样做是告诉Spring使用两个文件查找属性,jar / war中的文件,以及文件系统中任何位置的文件。 ignore-resource-not-found意味着如果找不到其中一个文件,Spring就不会抱怨。
使用此设置,第二个文件可以由DevOps人员控制,并且可以包含他们选择的任何内容,从而覆盖类路径属性文件文件中的任何属性。
更新:
您可以在配置类
中使用以下bean对Java Config执行相同操作@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
final PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
Resource[] resources = new Resource[ ] {
new ClassPathResource( "config.properties" ),
new FileSystemResource("/path/config/config.properties")
};
pspc.setLocations( resources );
pspc.setIgnoreResourceNotFound(true);
pspc.setIgnoreUnresolvablePlaceholders(false);
return pspc;
}
答案 2 :(得分:5)
我已经半天敲打了我的头,而我最终得到的解决方案是其他答案的组合。
Bart的解决方案对我来说有使用动态prop文件的缺点,因此我的IDE“忘记了”关于它的一切,并且无法告诉我使用了哪些属性以及在哪里。 Geoand解决方案对我来说有一个缺点,即配置文件“应该在某处”。我可以看到为什么在某些情况下这很方便,但我倾向于在任何环境中都可以部署一个单独的工件,因此我不必在战略位置“停放”文件以供应用程序选择。因此我的解决方案是:
- config.properties (default properties, usually local development env)
- config.staging.properties (overrides depending on the env)
- config.prod.properties (overrides depending on the env)
<context:property-placeholder ignore-resource-not-found="true"
location="config.properties,
config-${profile}.properties"/>
神奇的是ignore-resource-not-found="true"
,它允许我在不设置任何特殊profile
变量的情况下触发本地开发环境。丢失的文件将被忽略。
相反,我在我的各种部署环境中设置了该变量,例如-Dprofile=staging
,然后找到该文件并应用覆盖。
答案 3 :(得分:1)
在我上面的情况下,任何解决方案都行不通,所以我从头开始做了一些google,最后找到了一些可行的解决方案。
我对上述类进行了如下修改:
@Configuration
@PropertySource("classpath:application-${spring.profiles.active}.properties")
public class MyApplicationConfiguration {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
return configurer;
}
}
不是在方法内部定义动态文件名。我正在定义以下文件名,这对我来说很神奇。
@PropertySource(“ classpath:application-$ {spring.profiles.active} .properties”)
在课程顶部。通过遵循Bart的解决方案,我没有遇到任何错误,但是却使所有属性值都在属性文件中定义为null。
通过使用我的方法,spring能够识别VM参数和环境变量中定义的属性。 注意:我使用的是非春季启动项目。
答案 4 :(得分:0)
您可以在启动服务器时在Spring启动应用程序中添加-Dspring.profile.active = local。它将选择application-local.properties