<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<!-- 配置dataSource -->
<bean id="basicDataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
在实际的工作中,上述的代码十分常见,可以看到basicDataSource的property的value值都是变量。那么这些变量的值从何而来?
检索下,得知,这些变量的值都来自properties文件。那么properties文件中的键值对又是怎么被加载到内存, 从而可以赋值给value的呢?
主要是因为PropertyPlaceholderConfigurer这个spring类,将系统的相关变量分离到了一个properties文件中,便于系统一直、切换。
查看源代码,可以发现,locations属性定义在PropertyPlaceholderConfigurer的祖父类 PropertiesLoaderSupport中,而location只有 setter方法。类似于这样的配置,在spring的源程序中很常见的。
PropertyPlaceholderConfigurer如果在指定的Properties文件中找不到你想使用的属性,它还会在Java的System类属性中查找。
我们可以通过System.setProperty(key, value)或者java中通过-Dnamevalue来给Spring配置文件传递参数。
在jdbc.properties中可以看到。
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc\:mysql\://localhost\:3306/mail?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=passw0rd
jdbc.minPoolSize=3
jdbc.maxPoolSize=20
jdbc.initialPoolSize=3
jdbc.maxIdleTime=20
如果想要对公司的配置中心的配置文件做这种操作,必须覆盖PropertyPlaceholderConfigurer类中的postProcessBeanFactory()函数。贴出代码:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.io.support.PropertiesLoaderSupport;
public class ConfcenterBasedPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private IConfCenterClient confCenterClient;
private String confcenter;
private Map<String, String> props;
private String xml = XML_FILE_ENTENSION;
private static final String XML_FILE_ENTENSION = ".xml";
public void setXmlFileExtension(String xml) {
this.xml = xml;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
confCenterClient = ConfCenterClientFactory.getConfCenterClient(confcenter);
Properties properties = new Properties();
for (String prop : props.keySet()) {
String[] ps = confCenterClient.getConfFileAllForPlaceHolder(props.get(prop));
// �������, ��֤���ǵ����ȼ�ok
for (int i = ps.length - 1; i >= 0; --i) {
if (ps[i] == null || "".equals(ps[i].trim())) {
continue;
}
Properties tmp = new Properties();
InputStream is = new ByteArrayInputStream(ps[i].getBytes());
try {
if (ps[i].endsWith(this.xml)) {
tmp.loadFromXML(is);
} else {
tmp.load(is);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
for (Object key : tmp.keySet()) {
properties.put(prop + ":" + key, tmp.get(key));
}
properties.putAll(tmp);
}
}
processProperties(beanFactory, properties);
}
public String getConfcenter() {
return confcenter;
}
public void setConfcenter(String confcenter) {
this.confcenter = confcenter;
}
public Map<String, String> getProps() {
return props;
}
public void setProps(Map<String, String> props) {
this.props = props;
}
}
贴一个可以参考的博文:http://blog.csdn.net/sz_bdqn/article/details/6666262