Spring placeholder doesn't resolve properties in JavaConfig

11,690

Solution 1

Update to use configure PropertySourcesPlaceholderConfigurer. Just having @PropertySource annotation will not be sufficient:

@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
    return new PropertySourcesPlaceholderConfigurer();
}

@PropertySource annotation does not automatically register a PropertySourcesPlaceholderConfigurer with Spring. Hence we need to explicitly configure PropertySourcesPlaceholderConfigurer

Below JIRA ticket has more information on the rationale behind this design:

https://jira.spring.io/browse/SPR-8539

UPDATE: Created simple Spring boot application to use nested properties. It is working fine with the above configuration.

https://github.com/mgooty/property-configurer/tree/master/complete

Solution 2

Another option is to import PropertyPlaceholderAutoConfiguration.class.

import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;

@Import(PropertyPlaceholderAutoConfiguration.class)

The annotation includes a PropertySourcesPlaceholderConfigurer in the context if it doesn't exist.

Share:
11,690
herau
Author by

herau

Software Engineer at Dassault Systèmes

Updated on July 26, 2022

Comments

  • herau
    herau almost 2 years

    Currently i have a Spring xml configuration (Spring 4) which load a properties file.

    context.properties

    my.app.service = myService
    my.app.other = ${my.app.service}/sample
    

    Spring xml configuration

    <bean id="contextProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="ignoreResourceNotFound" value="true" />
        <property name="fileEncoding" value="UTF-8" />
        <property name="locations">
            <list>
                <value>classpath:context.properties</value>
            </list>
        </property>
    </bean>
    <bean id="placeholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreResourceNotFound" value="true" />
        <property name="properties" ref="contextProperties" />
        <property name="nullValue" value="@null" />
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    </bean>
    

    Bean which use the properties

    @Component
    public class MyComponent {
    
        @Value("${my.app.other}")
        private String others;
    
    }
    

    This works perfectly and the others value is MyService/sample, as excepted. But when i try to replace this configuration by a JavaConfig, the @Value in my component doesn't works in the same way. the value isn't myService/sample but ${my.app.service}/sample.

    @Configuration
    @PropertySource(name="contextProperties", ignoreResourceNotFound=true, value={"classpath:context.properties"})
    public class PropertiesConfiguration {
    
        @Bean
        public static PropertyPlaceholderConfigurer placeholder() throws IOException {
            PropertyPlaceholderConfigurer placeholder = new PropertyPlaceholderConfigurer();
            placeholder.setNullValue("@null");
            placeholder.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE);
            return placeholder;
        }
    
    }
    

    Did i miss something in the conversion from xml to Javaconfig ?

    ps : I also try to instantiate a PropertySourcesPlaceholderConfigurer instead of a PropertyPlaceholderConfigurer without more success.