java 可选的@PropertySource 位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17401583/
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
Optional @PropertySource location
提问by Gerhard Schlager
I'm using Spring 3.2 in a web application and I'd like to have a .properties
file within the classpath which contains default values. The user should be able to use JNDI to define a location where another .properties
is stored which overrides the default values.
我在 Web 应用程序中使用 Spring 3.2,并且我希望.properties
在类路径中有一个包含默认值的文件。用户应该能够使用 JNDI 来定义.properties
存储另一个覆盖默认值的位置。
The following works as long as the user has set the configLocation
as JNDI property.
只要用户设置了configLocation
as JNDI 属性,以下就可以工作。
@Configuration
@PropertySource({ "classpath:default.properties", "file:${java:comp/env/configLocation}/override.properties" })
public class AppConfig
{
}
However, the external overrides should be optional and so should the JNDI property.
但是,外部覆盖应该是可选的,JNDI 属性也应该是可选的。
Currently I get an exception (java.io.FileNotFoundException: comp\env\configLocation\app.properties (The system cannot find the path specified)
when the JNDI property is missing.
目前我得到一个异常(java.io.FileNotFoundException: comp\env\configLocation\app.properties (The system cannot find the path specified)
当 JNDI 属性丢失时。
How can I define optional .properties
that are used only when the JNDI property (configLocation
) is set? Is this even possible with @PropertySource
or is there another solution?
如何定义.properties
仅在设置 JNDI 属性 ( configLocation
)时使用的可选?这甚至可能@PropertySource
还是有其他解决方案?
采纳答案by vivo
Try the following. Create a ApplicationContextInitializer
请尝试以下操作。创建一个ApplicationContextInitializer
In a Web Context: ApplicationContextInitializer<ConfigurableWebApplicationContext>
and register it in the web.xml via:
在 Web 上下文中:ApplicationContextInitializer<ConfigurableWebApplicationContext>
并通过以下方式在 web.xml 中注册它:
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>...ContextInitializer</param-value>
</context-param>
In the ContextInitializer you can add your property files via classpath and file system (haven't tried JNDI though).
在 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);
}
}
The code above tries to find a property file per active profile (see: How to set active spring 3.1 environment profile via a properites file and not via an env variable or system property)
上面的代码尝试为每个活动配置文件查找一个属性文件(请参阅:如何通过属性文件而不是通过 env 变量或系统属性设置活动的 spring 3.1 环境配置文件)
回答by matsev
As of Spring 4, issue SPR-8371has been solved. Consequently, the @PropertySource
annotation has a new attribute called ignoreResourceNotFound
that has been added for exactly this purpose. Additionally, there is also the new @PropertySourcesannotation which allows implementations like:
从 Spring 4 开始,问题SPR-8371已经解决。因此,@PropertySource
注释有一个名为的新属性ignoreResourceNotFound
,正是为此目的而添加的。此外,还有新的@PropertySources注释,它允许实现如下:
@PropertySources({
@PropertySource("classpath:default.properties"),
@PropertySource(value = "file:/path_to_file/optional_override.properties", ignoreResourceNotFound = true)
})
回答by Koraktor
If you're not yet on Spring 4 (see matsev's solution), here's a more verbose, but roughly equivalent solution:
如果您还没有使用 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) {}
}
}