java 根据配置文件在 Spring 中加载属性文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10669474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 02:01:52  来源:igfitidea点击:

Load properties file in Spring depending on profile

javaspring

提问by Luciano

I have a Spring 3.1 application. Let's say it has an XML with the following content:

我有一个 Spring 3.1 应用程序。假设它有一个包含以下内容的 XML:

<context:property-placeholder location="classpath:somename.properties" />

<context:property-placeholder location="classpath:xxx.properties" />

I would like some.properties to be always loaded (let's assume it exists), but the xxx part of the second place holder to be replaced by some name depending on the active profile. I've tried with this:

我希望 some.properties 总是被加载(假设它存在),但第二个占位符的 xxx 部分将根据活动配置文件替换为某个名称。我试过这个:

<beans profile="xx1">
    <context:property-placeholder location="classpath:xx1.properties" />
</beans>

<beans profile="xx2">
    <context:property-placeholder location="classpath:xx2.properties" />
</beans>

Also, both files have properties with the same key but different value.

此外,这两个文件的属性具有相同的键但不同的值。

But it didn't work as some later bean that has a placeholder for one property whose key is defined in xx1.properties (and xx2.properties) makes Spring complain that the key is not found in the application context.

但它并没有像一些后来的 bean 那样工作,该 bean 具有一个属性的占位符,其键定义在 xx1.properties(和 xx2.properties)中,这使 Spring 抱怨在应用程序上下文中找不到该键。

采纳答案by bobjamin

I have decided to submit and answer to this as it has not yet been accepted. It may not be what you are looking for specifically but it works for me. Also note that i am using the new annotation driven configuration however it can be ported to the xml config.

我决定提交并回答这个问题,因为它尚未被接受。它可能不是您要特别寻找的,但它对我有用。另请注意,我正在使用新的注释驱动配置,但它可以移植到 xml 配置。

I have a properties file for each environment(dev.properties, test.properties etc)

我有每个环境的属性文件(dev.properties、test.properties 等)

I then have a RootConfig class that is the class that is used for all the configuration. All that this class has in it is two annotations: @Configuration and @ComponentScan(basePackageClasses=RootConfig.class). This tells it to scan for anything in the same package as it.

然后我有一个 RootConfig 类,它是用于所有配置的类。这个类只有两个注释:@Configuration 和@ComponentScan(basePackageClasses=RootConfig.class)。这告诉它扫描与它相同的包中的任何东西。

There is then a Configuration Containing all my normal configuration sitting wherever. There is also a configuration for each environment in the same package as the root configuration class above.

然后有一个包含我所有正常配置的配置位于任何地方。上面的根配置类在同一个包中也有每个环境的配置。

The environment specific configurations are simply marker classes that have the following annotations to point it to the environment specific properties files:

特定于环境的配置只是标记类,具有以下注释以将其指向特定于环境的属性文件:

@Configuration
@PropertySource("classpath:dev.properties")
@Import(NormalConfig.class)
@Profile("dev")

The import tells it to bring in the normal config class. But when it gets in there it will have the environment specific properties set.

导入告诉它引入普通的配置类。但是当它进入那里时,它将设置环境特定的属性。

回答by Sebastien Lorber

You can do:

你可以做:

  <context:property-placeholder location="classpath:${spring.profiles.active}.properties" />

It works fine, but is perhaps not adapted when using multiple profiles in the same time.

它工作正常,但可能不适用于同时使用多个配置文件。



When declaring 2 property placeholders, if the 1st one does not contain all the applications keys, you should put the attribute ignoring unresolvable = true, so that the 2nd placeholder can be used. I'm not sure if it is what you want to do, it may if you want both xx1 and xx2 profiles be active in the same time.

声明2个属性占位符时,如果第一个不包含所有应用程序键,则应将属性忽略unresolvable = true,以便可以使用第二个占位符。我不确定这是否是您想要做的,如果您希望 xx1 和 xx2 配置文件同时处于活动状态,则可能会这样做。

Note that declaring 2 propertyplaceholders like that make them independant, and in the declaration of xx2.properties, you can't reuse the values of xx1.properties.

请注意,像这样声明 2 个属性占位符会使它们独立,并且在 xx2.properties 的声明中,您不能重用 xx1.properties 的值。



If you need something more advanced, you can register your PropertySources on application startup.

如果您需要更高级的东西,您可以在应用程序启动时注册您的 PropertySource。

web.xml

网页.xml

  <context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.xxx.core.spring.properties.PropertySourcesApplicationContextInitializer</param-value>
  </context-param>

file you create:

您创建的文件:

public class PropertySourcesApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

  private static final Logger LOGGER = LoggerFactory.getLogger(PropertySourcesApplicationContextInitializer.class);

  @Override
  public void initialize(ConfigurableApplicationContext applicationContext) {
    LOGGER.info("Adding some additional property sources");
    String profile = System.getProperty("spring.profiles.active");
    // ... Add property sources according to selected spring profile 
    // (note there already are some property sources registered, system properties etc)
    applicationContext.getEnvironment().getPropertySources().addLast(myPropertySource);
  }

}

Once you've done it you just need to add in your context:

完成后,您只需要在上下文中添加:

<context:property-placeholder/>

Imho it's the best way to deal with spring properties, because you do not declare local properties everywhere anymore, you have a programmatic control of what is happening, and property source xx1 values can be used in xx2.properties.

恕我直言,这是处理 spring 属性的最佳方法,因为您不再在任何地方声明本地属性,您可以对发生的事情进行编程控制,并且可以在 xx2.properties 中使用属性源 xx1 值。



At work we are using it and it works nicely. We register 3 additional property sources: - Infrastructure: provided by Puppet - Profile: a different property loaded according to the profile. - Common: contains values as default, when all profiles share the same value etc...

在工作中,我们正在使用它,它运行良好。我们注册了 3 个额外的属性源: - 基础设施:由 Puppet 提供 - 配置文件:根据配置文件加载的不同属性。- 通用:包含默认值,当所有配置文件共享相同的值等...