在Spring中允许把xml配置文件中的一些参数配置到properties中,例如像数据源中的属性配置,把数据源中的属性放到properties中更利于后期的修改和扩展。
Spring中此功能的核心是配置PropertyOverrideConfigurer属性覆盖器,目的是用来指定properties文件的位置,配置覆盖器有下面两种方法:
1、<context:property-placeholder location="classpath:jdbc.properties"/>
2、<bean id="propertyConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:jdbc.properties</value>
</property>
</bean>
上面是指对一个properties文件的配置,如果有多个properties文件第一种配置在location的属性值相互逗号隔开,在第二种引入<list></list>来配置即可。
配置完PropertyOverrideConfigurer属性覆盖器后就可以把替换的内容用形如${key}el表达式的字符串来替换。如下:
<bean id="dbutil" class="com.cph.bean.DBUtil">
<property name="name" value="${name}" />
<property name="drivername" value="${drivername}" />
<property name="url" value="${url}" />
<property name="pwd" value="${pwd}" />
</bean>
jdbc.properties文件如下:
name=scott
drivername=oracle:jdbc:driver:OracleDirver
url=jdbc:oracle:thin:@127.0.0.1:1521:hsp
pwd=tiger
开发一个测试类如下:
public class App1 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
XmlBeanFactory xmlBeanFactory=
new XmlBeanFactory(
new ClassPathResource("ApplicationContext.xml"));
DBUtil dbUtil=(DBUtil)xmlBeanFactory.getBean("dbutil2");
System.out.println(dbUtil.getDrivername()+" "+dbUtil.getName());
}
}
此时输出的结果并不是我们想看到的:
oracle:jdbc:driver:OracleDirver scott
如是输出了:
${drivername} ${name}
为什么?从返回来的结果,觉得并没有去properties文件中读取value,而是把${xxx}当字符串了,我们检查一下配的properties路劲并没有错,并且如果是配置的路径错误,会报下面的错误,但它并没有报错(为了显示不是路劲问题故意配错的路径),说明不是路经问题:
java.io.FileNotFoundException: class path resource [//jdbc.properties] cannot be opened because it does not exist
配置PropertyOverrideConfigurer属性覆盖器和用${xxxx}取值也没有错,这个是spring开发文档给的。初看觉得已经进入死胡同了,但我们还忘记了一个可能会引起这个问题大地方就是spring中加载配置文件的方式。
在Spring中加载xml文件的配置文件的方式主要有如下几种:
1、XmlBeanFactory
2、ClassPathXmlApplicationContext
3、FileSystemXmlApplicationContext
4、XmlWebApplicationContext
加载这些容器的配置文件的xml有一下几种常见的方法:
1:引用资源用XmlBeanFactory(不能实现多个文件相互引用)
Resource resource = new ClassPathResource("appcontext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
从factory中获取相应资源文件中的bean,但是这种bean读不到引用了其他文件中的bean!
2:引用应用上下文用ClassPathXmlApplicationContext
ApplicationContext factory=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
ApplicationContext factory=new ClassPathXmlApplicationContext("conf/userConfig.xml"); // src/conf 目录下的
ApplicationContext factory=new ClassPathXmlApplicationContext("file:G:/Test/src/appcontext.xml");
3:用文件系统的路径引用应用上下文用
FileSystemXmlApplicationContext
ApplicationContext factory=new FileSystemXmlApplicationContext("src/applicationContext.xml");
ApplicationContext factory=new FileSystemXmlApplicationContext("classpath:appcontext.xml");
ApplicationContext factory=new FileSystemXmlApplicationContext("file:G:/Test/src/appcontext.xml");
ApplicationContext factory=new FileSystemXmlApplicationContext("G:/Test/src/appcontext.xml");
4:Web工程定制的加载方法 XmlWebApplicationContext
ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext );
通过上面的对几种加载配置文件的方式我们可以看出XmlBeanFactory方式是不能不能获取其他文件的资源的,所以也就是这个原因造成我们无法得到我们想要的结果,把加载xml方式修改ClassPathXmlApplicationContext即可,问题解决