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;
所有内容均按所需顺序正确获取:
如果我像那样向 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 装饰变量;
- 如果省略了 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)
})
我有一个 属性 配置 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;
所有内容均按所需顺序正确获取:
如果我像那样向 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 装饰变量;
- 如果省略了 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)
})