Local和prod环境的不同属性变量(Spring)

Tus*_*har 27 spring spring-mvc

我正在开发一个Spring Web应用程序,我需要在其中拥有变量,它们在本地环境中具有不同的价值,在生产环境中具有其他价值.

对于Eg(文件上传目录).我的文件上传目录对于本地和prod环境是不同的.

目前我通过检查主机名(如果是'localhost',然后是A else B)并采用这种方法来做到这一点.有另一种方法可以通过属性文件解决这个问题,有没有人提供我如何处理它的指针?

Bar*_*art 20

您可以根据当前弹簧配置文件或配置文件加载属性.要设置弹簧配置文件,我主要设置一个名为spring.profiles.active所需值的系统属性,例如developmentproduction.

这个概念非常简单.从系统属性中读取当前活动的配置文件.构建文件名并使用a加载属性文件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;
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以导入多个带注释的配置类@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 {}
Run Code Online (Sandbox Code Playgroud)

正如埃默森·法鲁吉亚(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...
    }
}
Run Code Online (Sandbox Code Playgroud)


geo*_*and 8

一个完全不涉及Spring Profiles的解决方案是使用如下内容:

<context:property-placeholder location="classpath*:config.properties,file:/path/config/config.properties"
                              ignore-unresolvable="false" ignore-resource-not-found="true"/>
Run Code Online (Sandbox Code Playgroud)

这样做是告诉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;
}
Run Code Online (Sandbox Code Playgroud)


nam*_*999 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"/>
Run Code Online (Sandbox Code Playgroud)

神奇的是ignore-resource-not-found="true"允许我在没有设置任何特殊profile变量的情况下触发我的本地开发环境.丢失的文件将被忽略.

相反,我在我的各种部署环境中设置了该变量,例如-Dprofile=staging,然后找到该文件并应用覆盖.