英文:
Environment variables not converted to system properties
问题
在处理一个基于旧版 Spring 的应用程序(Spring 4.3)时,我遇到了一个奇怪的行为:Spring 无法解析环境变量。
例如,我有这个环境变量:HOST_SERVICE_BASE_URL
,当我在应用程序中使用${host.service.base.url}
引用它时,属性未能解析,导致应用程序在启动时失败。
Caused by: java.lang.IllegalArgumentException: 无法解析占位符 'host.service.base.url' 中的值 "${host.service.base.url}"
我为属性解析定义了以下 bean:
@Bean
public PropertiesFactoryBean applicationProperties(ResourceLoader resourceLoader) {
PropertiesFactoryBean propertiesFactory = new PropertiesFactoryBean();
propertiesFactory.setLocations(
resourceLoader.getResource("/WEB-INF/config/application.properties"),
resourceLoader.getResource("/WEB-INF/config/application-dev.properties")
);
return propertiesFactory;
}
以及:
<bean id="dataConfigPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="searchSystemEnvironment" value="true"/>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="properties" ref="applicationProperties"/>
</bean>
英文:
Working on a legacy Spring based application (Spring 4.3), I have a strange behavior: environment variables are not resolved by Spring.
For example I have this environment variable: HOST_SERVICE_BASE_URL
, when I refer to it in the application with ${host.service.base.url}
the property is not resolved and the application fails during start up.
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'host.service.base.url' in value "${host.service.base.url}
I defined these beans for property resolution:
@Bean
public PropertiesFactoryBean applicationProperties( ResourceLoader resourceLoader ) {
PropertiesFactoryBean propertiesFactory = new PropertiesFactoryBean();
propertiesFactory.setLocations( resourceLoader.getResource( "/WEB-INF/config/application.properties" ),
resourceLoader.getResource( "/WEB-INF/config/application-dev.properties" ) );
return propertiesFactory;
}
And
<bean id="dataConfigPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="searchSystemEnvironment" value="true"/>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="properties" ref="applicationProperties"/>
</bean>
答案1
得分: 2
你正在使用(现已不建议使用的)PropertyPlaceholderConfigurer
,虽然它可以查看系统环境,但缺少将这些属性映射到值的功能。即HOST_SERVICE_BASE_URL
没有映射为host.service.base.url
。
该支持仅在使用PropertySourcesPlaceholderConfigurer
时才可用,它会自动注册并在Spring 5.2建议使用(但自3.1起可用)时进行查询。
<bean id="dataConfigPropertyConfigurer"
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="properties" ref="applicationProperties"/>
</bean>
或者在Java中替换applicationProperties
bean和XML部分。
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocations({"/WEB-INF/config/application.properties", /WEB-INF/config/application-dev.properties"});
configurer.setIgnoreResourceNotFound(true);
return configurer;
}
或者如果你坚持使用XML,可以使用<context:property-placeholder />
标签,它会自动执行此操作。
<context:property-placeholder properties="applicationProperties" ignore-resource-not-found="true" />
或者
<context:property-placeholder locations="/WEB-INF/config/application.properties,/WEB-INF/config/application-dev.properties" ignore-resource-not-found="true" />
英文:
You are using the (now deprecated) PropertyPlaceholderConfigurer
while that can consult the system environment it lacks the feature of mapping those properties to values. I.e HOST_SERVICE_BASE_URL
isn't mapped as host.service.base.url
.
That support is only available in the SystemEnvironmentPropertySource
which is automatically registered and consulted when using the PropertySourcesPlaceholderConfigurer
(recommended as of Spring 5.2, but available since 3.1).
<bean id="dataConfigPropertyConfigurer"
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="properties" ref="applicationProperties"/>
</bean>
Or in Java to replace the applicationProperties
bean and XML portion.
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocations({"/WEB-INF/config/application.properties", /WEB-INF/config/application-dev.properties"});
configurer.setIgnoreResourceNotFound(true);
return configurer;
}
Or if you really stick with XML use the <context:property-placeholder />
tag, which automatically does this.
<context:property-placeholder properties="applicationProperties" ignore-resource-not-found="true" />
or
<context:property-placeholder locations="/WEB-INF/config/application.properties,/WEB-INF/config/application-dev.properties" ignore-resource-not-found="true" />
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论