简体   繁体   中英

Spring Boot file properties are ignored and classpath properties are taken instead when the values are loaded to XML configuration

I have a property configuration bean looking like:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="false"/>
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="localOverride" value="false"/>
    <property name="locations">
        <list>
            <value>file://${emulator.config}</value>
            <value>classpath:emulator.properties</value>
            <value>file://${db.config}</value>
            <value>classpath:db.properties</value>
        </list>
    </property>
</bean>

The values from the first emulator config are taken in the code with @Value like:

@Value("${emulator.database.template.create}")
private String createDBPath;

All they are correctly taken in the desired order:

  1. If I supply the external file path to the jvm options like that

      java \\ -Dlog4j.configurationFile=/correctfullpath/log4j2.xml \\ -Dspring.config.location=/correctfullpath/application.properties \\ -Demulator.config=/correctfullpath/emulator.properties \\ -Ddb.config=/correctfullpath/db.properties -jar target/registrator-emulator.war 

I got the values loaded to @Value-decorated variables taken from the supplied /correctfullpath/emulator.properties ;

  1. If the jvm options are ommited, the values are taken from the classpath properties file within the jar

and something goes absolutelly different if I'm obtaining property values to the xml-configurated bean:

<bean id="manageDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${database.driver}"/>
    <property name="url" value="${database.url}"/>
    <property name="username" value="${database.user}"/>
    <property name="password" value="${database.password}"/>
</bean>

Here ${database.url} use to be taken from db.properties are ignoring values supplied with -Ddb.config=/correctfullpath/db.properties option; they are always taken from classpath property file from the jar. The only workaround (not very suitable for me) is to comment out the classpath property from the properties placeholder bean:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="false"/>
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="localOverride" value="false"/>
    <property name="locations">
        <list>
            <value>file://${emulator.config}</value>
            <value>classpath:emulator.properties</value>
            <value>file://${db.config}</value>
            <!--<value>classpath:db.properties</value>-->
        </list>
    </property>
</bean>

So is there any option to force classpath properties be ignored in xml configuration when the file properties are supplied?

UPD. According to advice of M. Deinum I tried toscwitch to Spring boot annotated configurration.

But I'm still have to comment out the classpath db.properties:

@Configuration
@PropertySources({@PropertySource("file://${emulator.config}"),
        @PropertySource("classpath:emulator.properties"),
        @PropertySource(value = "file://${statsd.config}",ignoreResourceNotFound = true),
        @PropertySource("classpath:statsd.properties"),
        @PropertySource(value = "file://${pools.config}",ignoreResourceNotFound = true),
        @PropertySource("classpath:pools.properties"),
        @PropertySource(value= "file://${db.config}"),
        //@PropertySource("classpath:db.properties")
        })

and here how I create the bean:

@Value("${database.driver}") private String dataBaseDriver;

@Value("${database.url}")
private String dataBaseUrl;

@Value("${database.user}")
private String dataBaseUser;

@Value("${database.password}")
private String dataBasePassword;




@Bean
@Primary
public DataSource manageDataSource() {
    return DataSourceBuilder
            .create()
            .username(dataBaseUser)
            .password(dataBasePassword)
            .url(dataBaseUrl)
            .driverClassName(dataBaseDriver)
            .build();
}

The root of the problem was in properties order!

Since the file properties override the classpath properties, they should be placed after the classpath ones:

@PropertySources({
        @PropertySource("classpath:emulator.properties"),
        @PropertySource(value = "file://${emulator.config}", ignoreResourceNotFound = true),
        @PropertySource("classpath:statsd.properties"),
        @PropertySource(value = "file://${statsd.config}",ignoreResourceNotFound = true),
        @PropertySource("classpath:pools.properties"),
        @PropertySource(value = "file://${pools.config}",ignoreResourceNotFound = true),
        @PropertySource("classpath:db.properties"),
        @PropertySource(value= "file://${db.config}",ignoreResourceNotFound = 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