Spring 当将值加载到 XML 配置时,引导文件属性被忽略,取而代之的是类路径属性

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

我有一个 属性 配置 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>

来自第一个模拟器配置的值在带有@Value 的代码中获取,例如:

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

所有内容均按所需顺序正确获取:

  1. 如果我像那样向 jvm 选项提供外部文件路径

      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
    

我将值加载到从提供的 /correctfullpath/emulator.properties 中获取的 @Value 装饰变量;

  1. 如果省略了 jvm 选项,则值取自 jar 中的类路径属性文件

如果我为 xml-configured 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>

此处 ${database.url} 用于从 db.properties 获取,忽略了 -Ddb.config=/correctfullpath/db.properties 选项提供的值;它们总是取自 jar 的类路径 属性 文件。唯一的解决方法(不太适合我)是从属性占位符 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>

那么,在提供文件属性时,是否有任何选项可以在 xml 配置中强制忽略类路径属性?

更新。根据 M. Deinum 的建议,我尝试切换到 Spring 引导注释配置。

但我仍然需要注释掉类路径 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")
        })

下面是我如何创建 bean:

@Value("${database.driver}") 私人字符串 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();
}

问题的根源在于属性顺序!

由于文件属性覆盖了类路径属性,它们应该放在类路径属性之后:

@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)
        })