Spring-Boot-Starter-Parent in combination with "property-placeholder" in XML-based Spring configuration

567 views Asked by At

In my POM I inherit from Spring Boot's "spring-boot-starter-parent":

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.2.RELEASE</version>
</parent>

According to the following Spring Boot documentation Spring Boot Parent changes the default filter token of the maven-resources-plugin from ${maven.token} to @maven.token@ to prevent conflicts with Spring-style placeholders. Background: the delimiters of Spring are identical to the Maven delimiters.

To my understanding: the change affects Maven property and not Spring property expansion. But maybe I'm wrong and it's vice versa?

Now, when using a "context:property-placeholder" in my XML based Spring application context configuration file imported via:

@Configuration
@ImportResource("spring/applicationContext-core.xml")
@EnableJpaRepositories
@EnableAutoConfiguration
public class StudyDayApplication {

    /**
     * This main is for using Spring Boot in case of a JAR file packaging.
     * 
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication.run(StudyDayApplication.class, args);
    }
}

the property expansion of Spring-specific keys does not work anymore. In my "application-core.xml" I use a Spring-specific "property-placeholder" to use externalized configuration properties. But I still want to use Spring-specific property delimiters (e.g. to expand the "jpa.driver.classname" in my "dataSource" bean).

...
<context:property-placeholder
        ignore-resource-not-found="false"
        location="classpath*:*.properties"/>
...
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
    <property name="driverClassName" value="${jpa.driver.classname}"/>
...

But the replacement in Spring only works when replacing the "${jpa.driver.classname}" by "@jpa.driver.classname@"

According to the following remark when adding the following XML attributes:

order="1"
ignore-unresolvable="true"

to the "property-placeholder" I do not get any exceptions during the Spring Boot startup telling me:

"Could not resolve placeholder 'jpa.driver.classname' in string value "${jpa.driver.classname}"

But I'm sure that the property expansion does not properly work as the "property-placeholder" ignores unresolvable items then. It leads to exceptions later when beans will be instantiated using non-expanded property keys. Setting only the "order=1" attribute does not help either.

Maybe, there is no need with Spring Boot to use a "property-placeholder" explicitly as Spring Boot searches for "application.properties" automatically within the application. But I do not want to switch to this approach.

Is there a way to use the "spring-boot-starter-parent" and keeping the typical Spring property expansion active?

1

There are 1 answers

0
Holger King On

I found my problem :-) It's not Spring that does provoke this strange effect but my configuration.

The problem was: the properties file was not located in the root folder of the class path but below. And as long as no property file is loaded no property expansion can be executed.

To find all *.properties files - even in sub-directories an ANT-style notation has to be used:

<context:property-placeholder
        ignore-resource-not-found="false"
        location="classpath*:**/*.properties"/>

Be careful: with this definition all "*.properties" files are found located in JAR files and any subfolder of the classpath root. Finally, they are merged to one single properties file. So, the memory consumption might increase!

Please consult the Spring documentation respectively the following comment @stackoverflow.com for further details.