可选的@PropertySource位置

Ger*_*ger 12 java spring spring-annotations

我在Web应用程序中使用Spring 3.2,我想.properties在类路径中包含一个包含默认值的文件.用户应该能够使用JNDI定义.properties存储另一个的位置,该位置将覆盖默认值.

只要用户设置了configLocationJNDI属性,以下内容就可以正常工作.

@Configuration
@PropertySource({ "classpath:default.properties", "file:${java:comp/env/configLocation}/override.properties" })
public class AppConfig
{
}
Run Code Online (Sandbox Code Playgroud)

但是,外部覆盖应该是可选的,JNDI属性也应该是可选的.

目前我得到一个例外(java.io.FileNotFoundException: comp\env\configLocation\app.properties (The system cannot find the path specified)当JNDI属性丢失时).

如何定义.properties仅在设置JNDI属性(configLocation)时使用的可选项?这是否可能@PropertySource或有其他解决方案?

mat*_*sev 39

截至4月4日,问题SPR-8371已经解决.因此,@PropertySource注释具有一个名为的新属性,该属性ignoreResourceNotFound已被添加用于此目的.此外,还有新的@PropertySources注释,允许实现如下:

@PropertySources({
    @PropertySource("classpath:default.properties"),
    @PropertySource(value = "file:/path_to_file/optional_override.properties", ignoreResourceNotFound = true)
})
Run Code Online (Sandbox Code Playgroud)

  • 请注意,根据`@ PropertySources` JavaDoc,在Java 8中,您可以直接将多个`@ PropertySource`注释应用于没有包装器的类. (3认同)
  • @ billc.cn挺对的.大约一年前我写了一篇关于`@ PropertySource`的[博客文章](http://www.jayway.com/2014/02/16/spring-propertysource/),其中我也提到了[Java 8的重复注释]( http://openjdk.java.net/jeps/120). (2认同)

Kor*_*tor 5

如果你还没有参加Spring 4(参见matsev的解决方案),这里有一个更详细,但大致相当的解决方案:

@Configuration
@PropertySource("classpath:default.properties")
public class AppConfig {

    @Autowired
    public void addOptionalProperties(StandardEnvironment environment) {
        try {
            String localPropertiesPath = environment.resolvePlaceholders("file:${java:comp/env/configLocation}/override.properties");
            ResourcePropertySource localPropertySource = new ResourcePropertySource(localPropertiesPath);
            environment.getPropertySources().addLast(localPropertySource);
        } catch (IOException ignored) {}
    }

}
Run Code Online (Sandbox Code Playgroud)


viv*_*ivo 3

尝试以下操作。创建一个ApplicationContextInitializer

在 Web 上下文中:ApplicationContextInitializer<ConfigurableWebApplicationContext>并通过以下方式在 web.xml 中注册:

<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>...ContextInitializer</param-value>
</context-param>
Run Code Online (Sandbox Code Playgroud)

在 ContextInitializer 中,您可以通过类路径和文件系统添加属性文件(但尚未尝试 JNDI)。

  public void initialize(ConfigurableWebApplicationContext applicationContext) {
    String activeProfileName = null;
    String location = null;

    try {
      ConfigurableEnvironment environment = applicationContext.getEnvironment();
      String appconfigDir = environment.getProperty(APPCONFIG);
      if (appconfigDir == null ) {
        logger.error("missing property: " + APPCONFIG);
        appconfigDir = "/tmp";
      }
      String[] activeProfiles = environment.getActiveProfiles();

      for ( int i = 0; i < activeProfiles.length; i++ ) {
        activeProfileName = activeProfiles[i];
        MutablePropertySources propertySources = environment.getPropertySources();
        location = "file://" + appconfigDir + activeProfileName + ".properties";
        addPropertySource(applicationContext, activeProfileName,
                location, propertySources);
        location = "classpath:/" + activeProfileName + ".properties";
        addPropertySource(applicationContext, activeProfileName,
                          location, propertySources);
      }
      logger.debug("environment: '{}'", environment.getProperty("env"));

    } catch (IOException e) {
      logger.info("could not find properties file for active Spring profile '{}' (tried '{}')", activeProfileName, location);
      e.printStackTrace();
    }
  }

  private void addPropertySource(ConfigurableWebApplicationContext applicationContext, String activeProfileName,
                                 String location, MutablePropertySources propertySources) throws IOException {
    Resource resource = applicationContext.getResource(location);
    if ( resource.exists() ) {
      ResourcePropertySource propertySource = new ResourcePropertySource(location);
      propertySources.addLast(propertySource);
    } else {
      logger.info("could not find properties file for active Spring profile '{}' (tried '{}')", activeProfileName, location);
    }
  }
Run Code Online (Sandbox Code Playgroud)

上面的代码尝试为每个活动配置文件查找属性文件(请参阅:如何通过属性文件而不是通过 env 变量或系统属性设置活动 spring 3.1 环境配置文件