我正在使用context:property-placeholder
讀取屬性文件。我如何訪問它們以編程方式(@Value
不起作用 - 我不知道在開發時屬性標題)?以編程方式訪問屬性佔位符創建的屬性
的主要問題是,因爲它是設置好的增長「父」框架
PS我不能改變applicationContext.xml
文件。這很奇怪,但Environment.getProperty
返回null
我正在使用context:property-placeholder
讀取屬性文件。我如何訪問它們以編程方式(@Value
不起作用 - 我不知道在開發時屬性標題)?以編程方式訪問屬性佔位符創建的屬性
的主要問題是,因爲它是設置好的增長「父」框架
PS我不能改變applicationContext.xml
文件。這很奇怪,但Environment.getProperty
返回null
不,你不能。 PropertyPlaceholderConfigurer
是BeanFactoryPostProcessor
,它在創建bean時只是「活着」的。遇到${property}
表示法時,它會嘗試根據其內部屬性解決該問題,但它不會使這些屬性對容器可用。
這就是說:類似的問題一次又一次地出現,建議的解決方案通常是to subclass PropertyPlaceHolderConfigurer
,並手動使該屬性可用於上下文。或use a PropertiesFactoryBean
Spring遵循Inversion Of Control方法,這意味着我們可以簡單地將特定的屬性注入到POJO中。但是有些情況下,當你想直接從你的代碼中獲得由名字給出的屬性時 - 有些人可能認爲它是反模式 - 這很明顯,但讓我們專注於如何去做。
下面的PropertiesAccessor
提供對Property Placeholder
加載的屬性的訪問,並封裝容器特定的內容。它也緩存找到的屬性,因爲在AbstractBeanFactory#resolveEmbeddedValue(String)
上調用並不便宜。
@Named
public class PropertiesAccessor {
private final AbstractBeanFactory beanFactory;
private final Map<String,String> cache = new ConcurrentHashMap<>();
@Inject
protected PropertiesAccessor(AbstractBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public String getProperty(String key) {
if(cache.containsKey(key)){
return cache.get(key);
}
String foundProp = null;
try {
foundProp = beanFactory.resolveEmbeddedValue("${" + key.trim() + "}");
cache.put(key,foundProp);
} catch (IllegalArgumentException ex) {
// ok - property was not found
}
return foundProp;
}
}
@Value
註釋適用於(在V3.2.2測試)春天的新版本 這裏是它是如何做:
地圖你的屬性在Spring配置文件文件
<!--Import Info:
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd-->
<context:property-placeholder location="classpath:/app-config.properties" />
在你的源文件夾裏面(root)創建app-config.properties
my.property=test
my.property2=test2
創建一個控制器類
@Controller
public class XRDSBuilder
{
@Value("${my.property}")
private String myProperty;
public String getMyProperty() { return myProperty; }
}
Spring會自動映射我的內容。屬性爲您的變量控制器
屬性值內:
my.list.property=test,test2,test3
Controller類配置:
@Value("#{'${my.list.property}'.split(',')}")
private List<String> myListProperty;
@Component("PropertySplitter")
public class PropertySplitter {
/**
* Example: one.example.property = KEY1:VALUE1,KEY2:VALUE2
*/
public Map<String, String> map(String property) {
return this.map(property, ",");
}
/**
* Example: one.example.property = KEY1:VALUE1.1,VALUE1.2;KEY2:VALUE2.1,VALUE2.2
*/
public Map<String, List<String>> mapOfList(String property) {
Map<String, String> map = this.map(property, ";");
Map<String, List<String>> mapOfList = new HashMap<>();
for (Entry<String, String> entry : map.entrySet()) {
mapOfList.put(entry.getKey(), this.list(entry.getValue()));
}
return mapOfList;
}
/**
* Example: one.example.property = VALUE1,VALUE2,VALUE3,VALUE4
*/
public List<String> list(String property) {
return this.list(property, ",");
}
/**
* Example: one.example.property = VALUE1.1,VALUE1.2;VALUE2.1,VALUE2.2
*/
public List<List<String>> groupedList(String property) {
List<String> unGroupedList = this.list(property, ";");
List<List<String>> groupedList = new ArrayList<>();
for (String group : unGroupedList) {
groupedList.add(this.list(group));
}
return groupedList;
}
private List<String> list(String property, String splitter) {
return Splitter.on(splitter).omitEmptyStrings().trimResults().splitToList(property);
}
private Map<String, String> map(String property, String splitter) {
return Splitter.on(splitter).omitEmptyStrings().trimResults().withKeyValueSeparator(":").split(property);
}
}
屬性值:
my.complex.property=test1:value1,test2:value2
控制器類:
@Value("#{PropertySplitter.map('${my.complex.property}')}")
Map<String, String> myComplexProperty;
找到答案:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="propertyConfigurer">
<property name="properties" ref="props" />
</bean>
<bean id="props" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="file:C:/CONFIG/settings.properties"/>
</bean>
我們用下面的方法來訪問屬性我們應用程序
<util:properties id="appProperties" location="classpath:app-config.properties" />
<context:property-placeholder properties-ref="appProperties"/>
然後,您可以使用限定符將屬性自動裝配到bean中。
@Component
public class PropertyAccessBean {
private Properties properties;
@Autowired
@Qualifier("appProperties")
public void setProperties(Properties properties) {
this.properties = properties;
}
public void doSomething() {
String property = properties.getProperty("code.version");
}
}
如果你有更復雜的屬性,你仍然可以使用ignore-resource-not-found和ignore-unresolvable。我們使用這種方法來外化我們的一些應用程序設置。
<util:properties id="appProperties" ignore-resource-not-found="true"
location="classpath:build.properties,classpath:application.properties,
file:/data/override.properties"/>
<context:property-placeholder ignore-unresolvable="true" properties-ref="appProperties"/>
讓我們asume你在 「父」 框架中定義的屬性文件
<bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:main.properties" />
</bean>
可以使用@Value註釋中這樣說:
@Value(value = "#{applicationProperties['my.app.property']}")
private String myProperty;
它在春季4面對錯誤: 索引進式「org.springframework.beans.factory.config.PropertyPlaceholderConfigurer」不支持 – 2017-09-14 05:46:24
像@SeanPatrickFloyd評論說:「_similar問題再次出現再次,建議的解決方案通常是子類PropertyPlaceHolderConfigurer,並使該屬性可用於上下文手動。或使用** PropertiesFactoryBean ** _。「我希望這可以幫助你:[閱讀價值從屬性文件在運行時](https://stackoverflow.com/questions/5665296/reading-valued-from-properties-file-at-runtime/5673678# 5673678) – 2017-10-23 13:59:02
請訪問http:// stackoverflow.com/questions/5172392/how-to-programmatically-resolve-property-placeholder-in-spring。從春季3開始似乎是可能的。 – Vadzim 2013-03-28 15:40:14