测试代码如下;
package com.yanek.ioc;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring-base.xml"})
public class MyTest3 {
@Test
public void test() {
System.out.println("CHARSET:"+com.yanek.util.ConfigConstants.CHARSET);
System.out.println("CONNECTTIMEOUT:"+com.yanek.util.ConfigConstants.CONNECTTIMEOUT);
System.out.println("READTIMEOUT:"+com.yanek.util.ConfigConstants.READTIMEOUT);
}
}
测试输出如下:
CHARSET:UTF-8
CONNECTTIMEOUT:1000
READTIMEOUT:5000
核心类:
package com.yanek.util;
import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
/**
* 自定义PropertyPlaceholderConfigurer返回properties内容
*/
public class CustomizedPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
/**
* 属性前缀,可以使用表达式${}。如果使用表达式,表示从属性文件中的字段读取。
* 如果为空,表示不使用前缀。
*/
private String prefix;
/**
* 需要注入的常量类名数组
*/
private String[] configureClasses;
@SuppressWarnings("unchecked")
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
throws BeansException {
super.processProperties(beanFactoryToProcess, props);
if (configureClasses == null) return;
String prefixValue = null;
if (prefix != null && !prefix.isEmpty()){
// 如果前缀是表达式,需要从属性中读取
Pattern p = Pattern.compile("\\$\\{(.*)\\}");
Matcher matcher = p.matcher(prefix);
prefixValue = prefix;
if (matcher.find()) {
String prefixKey = matcher.group(1);
prefixValue = props.getProperty(prefixKey);
}
}
// 遍历多个常量类
for (int i = 0; i < configureClasses.length; i++) {
Class c = null;
try {
c = Class.forName(configureClasses[i]);
} catch (ClassNotFoundException e) {
e.printStackTrace();
continue;
}
Field[] fields = c.getFields();
// 遍历属性列表,注入到常量字段中
for (Enumeration<?> k = props.propertyNames(); k.hasMoreElements();) {
String key = (String) k.nextElement();
// 遍历常量字段数组,找到与属性对应的常量字段
for (int j = 0; fields != null && j < fields.length; j++) {
// 取出字段名称,如果有前缀,需要加上前缀
String keyStr = fields[j].getName();
if (prefixValue != null && !prefixValue.isEmpty())
keyStr = prefixValue + "." + fields[j].getName();
// 判断常量字段是否有属性匹配,不区分大小写。
if (keyStr.equalsIgnoreCase(key)) {
// 从属性中取出字段值,并存到字段中
String value = props.getProperty(key);
if (value != null) {
value = value.trim();
// fields[j].setAccessible(true);
try {
if (Integer.TYPE.equals(fields[j].getType())) {
fields[j].setInt(null, Integer.parseInt(value));
} else if (Long.TYPE.equals(fields[j].getType())) {
fields[j].setLong(null, Long.parseLong(value));
} else if (Short.TYPE.equals(fields[j].getType())) {
fields[j].setShort(null, Short.parseShort(value));
} else if (Double.TYPE.equals(fields[j].getType())) {
fields[j].setDouble(null, Double.parseDouble(value));
} else if (Float.TYPE.equals(fields[j].getType())) {
fields[j].setFloat(null, Float.parseFloat(value));
} else if (Boolean.TYPE.equals(fields[j].getType())) {
fields[j].setBoolean(null, Boolean.parseBoolean(value));
} else {
fields[j].set(null, value);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
break;
}
}
}
}
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String[] getConfigureClasses() {
return configureClasses;
}
public void setConfigureClasses(String[] configureClasses) {
this.configureClasses = (configureClasses != null)? configureClasses.clone() : null;
}
public void setConfigureClass(String configureClass) {
this.configureClasses = new String[] {configureClass};
}
}
package com.yanek.util;
public class ConfigConstants {
public static int CONNECTTIMEOUT = 0;
public static int READTIMEOUT = 0;
public static String CHARSET = "";
}
属性文件:application.properties
CONNECTTIMEOUT=1000
READTIMEOUT=5000
CHARSET=UTF-8
spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-autowire="byName" default-lazy-init="false">
<!-- 从properties文件加载配置信息 -->
<bean id="propertyPlaceholderConfigurer"
class="com.yanek.util.CustomizedPropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
</list>
</property>
<property name="configureClasses">
<list>
<value>com.yanek.util.ConfigConstants</value>
</list>
</property>
</bean>
</beans>