fed*_*lov 40 spring properties
我正在阅读属性文件context:property-placeholder.如何以编程方式访问它们(@Value不起作用 - 我不知道开发时的属性标题)?
主要问题是我无法更改applicationContext.xml文件,因为它是由"父"框架设置的
PS.这很奇怪,但Environment.getProperty回归null
Sea*_*oyd 35
不,你不能.PropertyPlaceholderConfigurer是a BeanFactoryPostProcessor,它只是在bean创建过程中"活着".当遇到${property}符号时,它会尝试针对其内部属性解决该问题,但它不会使这些属性对容器可用.
也就是说:类似的问题一再出现,建议的解决方案通常是子类化PropertyPlaceHolderConfigurer并使属性可用于上下文.或者使用PropertiesFactoryBean
@Value
Run Code Online (Sandbox Code Playgroud)
注释适用于Spring的新版本(在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" />
Run Code Online (Sandbox Code Playgroud)在源文件夹内创建app-config.properties(root)
my.property=test
my.property2=test2
Run Code Online (Sandbox Code Playgroud)创建一个控制器类
@Controller
public class XRDSBuilder
{
@Value("${my.property}")
private String myProperty;
public String getMyProperty() { return myProperty; }
}
Run Code Online (Sandbox Code Playgroud)Spring会自动将my.property的内容映射到控制器内的变量
适当的价值:
my.list.property=test,test2,test3
Run Code Online (Sandbox Code Playgroud)
控制器类配置:
@Value("#{'${my.list.property}'.split(',')}")
private List<String> myListProperty;
Run Code Online (Sandbox Code Playgroud)
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
适当的价值:
my.complex.property=test1:value1,test2:value2
Run Code Online (Sandbox Code Playgroud)
控制器类:
@Value("#{PropertySplitter.map('${my.complex.property}')}")
Map<String, String> myComplexProperty;
Run Code Online (Sandbox Code Playgroud)
小智 8
我们使用以下方法来访问应用程序的属性
<util:properties id="appProperties" location="classpath:app-config.properties" />
<context:property-placeholder properties-ref="appProperties"/>
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用限定符将bean自动装配到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");
}
}
Run Code Online (Sandbox Code Playgroud)
如果您有更复杂的属性,您仍然可以使用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"/>
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
64170 次 |
| 最近记录: |