简体   繁体   中英

Environment variables not converted to system properties

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>

You are using the (now deprecated) PropertyPlaceholderConfigurer while that can consult the system environment it lacks the feature of mapping those properties to values. Ie 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" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM