Spring里PropertyPlaceholderConfigurer类的使用
1. PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现,也就是 BeanFactoryPostProcessor接口的一个实现。PropertyPlaceholderConfigurer可以将上下文(配置文 件)中的属性值放在另一个单独的标准java Properties文件中去。在XML文件中用${key}替换指定的properties文件中的值。这样的话,只需要对properties文件进 行修改,而不用对xml配置文件进行修改。
2.在Spring中,使用PropertyPlaceholderConfigurer可以在XML配置文件中加入外部属性文件,当然也可以指定外部文件的编码,如:

<bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>conf/sqlmap/jdbc.properties</value>
</property>
<property name="fileEncoding">
<value>UTF-8</value>
</property>
</bean>

当然也可以引入多个属性文件,如:

<bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/mail.properties</value>
<value>classpath: conf/sqlmap/jdbc.properties</value>//注意这两种value值的写法
</list>
</property>
</bean>

3.譬如,jdbc.properties的内容为:

jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost/mysqldb?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=round; jdbc.username=root jdbc.password=123456

4.那么在spring配置文件中,我们就可以这样写:

<bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath: conf/sqlmap/jdbc.properties </value>
</list>
</property>
</bean>
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">
<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>

5.这样,一个简单的数据源就设置完毕了。可以看出:PropertyPlaceholderConfigurer起的作用就是将占位符指向的数据库配置信息放在bean中定义的工具。
6.查看源代码,可以发现,locations属性定义在PropertyPlaceholderConfigurer的祖父类 PropertiesLoaderSupport中,而location只有 setter方法。类似于这样的配置,在spring的源程序中很常见的。
PropertyPlaceholderConfigurer如果在指定的Properties文件中找不到你想使用的属性,它还会在Java的System类属性中查找。
我们可以通过System.setProperty(key, value)或者java中通过-Dnamevalue来给Spring配置文件传递参数。
为简化PropertyPlaceholderConfigurer的使用,Spring提供了<context:property-placeholder/>元素。下面给出了配置示例,启用它后,开发者便不用配置PropertyPlaceholderConfigurer对象了。
- <context:property-placeholder location="userinfo.properties"/>
PropertyPlaceholderConfigurer内置的功能非常丰富,如果它未找到${xxx}中定义的xxx键,它还会去JVM系统属性(System.getProperty())和环境变量 (System.getenv())中寻找。通过启用systemPropertiesMode和searchSystemEnvironment属性,开发者能够控制这一行为。
这个在spring中配置文件中是非常常用的。
context:property-placeholder大大的方便了我们数据库的配置。
- 只需要在spring的配置文件里添加一句:<context:property-placeholder?location="classpath:jdbc.properties"/>?即可,这里location值为参数配置文件的位置,参数配置文件通常放在src目录下,而参数配置文件的格式跟java通用的参数配置文件相同,即键值对的形式,例如:
- #jdbc配置
- test.jdbc.driverClassName=com.mysql.jdbc.Driver
- test.jdbc.url=jdbc:mysql://localhost:3306/test
- test.jdbc.username=root
- test.jdbc.password=root
这样一来就可以为spring配置的bean的属性设置值了,比如spring有一个jdbc数据源的类DriverManagerDataSource
在配置文件里这么定义bean:
<bean id="testDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${test.jdbc.driverClassName}"/>
<property name="url" value="${test.jdbc.url}"/>
<property name="username" value="${test.jdbc.username}"/>
<property name="password" value="${test.jdbc.password}"/>
</bean>
这样修改起来也方便,也统一的这个规范。
另外需要注意的是,如果遇到下面着着这种问题:
A模块和B模块都分别拥有自己的Spring XML配置,并分别拥有自己的配置文件:
A模块的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"
- xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
- <context:property-placeholder location="classpath*:conf/conf_a.properties"/>
- <bean class="com.xxx.aaa.Bean1"
- p:driverClassName="${modulea.jdbc.driverClassName}"
- p:url="${modulea.jdbc.url}"
- p:username="${modulea.jdbc.username}"
- p:password="${modulea.jdbc.password}"/>
- </beans>
conf/conf_a.properties:
- modulea.jdbc.driverClassName=com.mysql.jdbc.Driver
- modulea.jdbc.username=cartan
- modulea.jdbc.password=superman
- modulea.jdbc.url=jdbc:mysql://127.0.0.1:3306/modulea?useUnicode=true&characterEncoding=utf8
B模块的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"
- xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
- <context:property-placeholder location="classpath*:conf/conf_b.properties"/>
- <bean class="com.xxx.bbb.Bean1"
- p:driverClassName="${moduleb.jdbc.driverClassName}"
- p:url="${moduleb.jdbc.url}"
- p:username="${moduleb.jdbc.username}"
- p:password="${moduleb.jdbc.password}"/>
- </beans>
conf/conf_b.properties:
- moduleb.jdbc.driverClassName=com.mysql.jdbc.Driver
- moduleb.jdbc.username=cartan
- moduleb.jdbc.password=superman
- moduleb.jdbc.url=jdbc:mysql://127.0.0.1:3306/modulea?useUnicode=true&characterEncoding=utf8
单独运行A模块,或单独运行B模块都是正常的,但将A和B两个模块集成后运行,Spring容器就启动不了了:
Could not resolve placeholder 'moduleb.jdbc.driverClassName' in string value "${moduleb.jdbc.driverClassName}"
原因:Spring容器采用反射扫描的发现机制,在探测到Spring容器中有一个org.springframework.beans.factory.config.PropertyPlaceholderConfigurer的Bean就会停止对剩余PropertyPlaceholderConfigurer的扫描
spring容器中最多只能定义一个context:property-placeholder,不然就出现那种个错误,那如何来解决上面的问题呢?
A和B模块去掉
- <context:property-placeholder location="classpath*:conf/conf_b.properties"/>
然后重新写个xml:
- <?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"
- xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
- <context:property-placeholder location="classpath*:conf/conf*.properties"/>
- <import resource="a.xml"/>
- <import resource="b.xml"/>
- </beans>

Spring里PropertyPlaceholderConfigurer类的使用的更多相关文章
- Spring 后置处理器 PropertyPlaceholderConfigurer 类(引用外部文件)
一.PropertyPlaceholderConfigurer类的作用 PropertyPlaceholderConfigurer 是 BeanFactory 后置处理器的实现,也是 BeanFact ...
- spring源码分析系列 (5) spring BeanFactoryPostProcessor拓展类PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer解析
更多文章点击--spring源码分析系列 主要分析内容: 1.拓展类简述: 拓展类使用demo和自定义替换符号 2.继承图UML解析和源码分析 (源码基于spring 5.1.3.RELEASE分析) ...
- 在普通Java类里使用spring里注入的service、dao等
版权声明:本文为博主武伟峰原创文章,转载请注明地址http://blog.csdn.net/tianyaleixiaowu. 在spring管理的web项目里,譬如Struts和spring的项目,配 ...
- spring读取配置文件PropertyPlaceholderConfigurer类的使用
这里主要介绍PropertyPlaceholderConfigurer这个类的使用,spring中的该类主要用来读取配置文件并将配置文件中的变量设置到上下文环境中,并进行赋值. 一.此处使用list标 ...
- spring中propertyplaceholderconfigurer简介
Spring的框架中为您提供了一个 BeanFactoryPostProcessor 的实作类别: org.springframework.beans.factory.config.PropertyP ...
- PropertyPlaceholderConfigurer类的使用注意
如果你在spring的applicationcontext.xml中需要使用属性配置文件,那PropertyPlaceholderConfigurer这个类就是必须的. <bean class= ...
- Spring的PropertyPlaceholderConfigurer应用
Spring 利用PropertyPlaceholderConfigurer占位符 1. PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现,也就是BeanFa ...
- Spring Boot普通类调用bean
1 在Spring Boot可以扫描的包下 假设我们编写的工具类为SpringUtil. 如果我们编写的SpringUtil在Spring Boot可以扫描的包下或者使用@ComponentScan引 ...
- spring启动component-scan类扫描加载过程(转)
文章转自 http://www.it165.net/pro/html/201406/15205.html 有朋友最近问到了 spring 加载类的过程,尤其是基于 annotation 注解的加载过程 ...
随机推荐
- 5. Longest Palindromic Substring
Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...
- Python基础(二)之字符串
字符串在python语言中极为常用,下面就带大家来一起回顾一下字符串常用的方法: 1.count 作用:统计字符串中字符的个数 例: str_yu = 'xiAoyuhaha' print(str_y ...
- 【原创】Java批量反编译利器(jd-gui)介绍
Java反编译利器(jd-gui)介绍 当要做白盒测试或安全测试时,我们需要借助工具扫描被测代码,相信大家都遇到过没有源代码,而需要反编译的情形吧,也可能大家用过jad工具,我这里介绍下方便的工具jd ...
- 学习游戏渲染(Shader)的用处
本文在讨论的主题并不限于具体引擎或具体语言,为了说明方便可能会提到Unity的一些内容. 最近渐渐发现很多从事游戏开发的新人,对于学会写Shader似乎总是有几分神往,但一般入了门或者学了一段时间后 ...
- ubuntu 13.10 svn工具 rabbitvcs 安装
ubuntu 版本:13.10:桌面模式默认:unity :文件管理器:nautilus
- ssh整合需要那些jar
struts2 commons-logging-1.0.4.jar -------主要用于日志处理 freemarker-2.3.8.jar ------- 模板相关操作需要包 ognl-2.6.1 ...
- Oracle 常见函数
1.把数字转换为字符串:To_char(数字) 2.Oracle 拼接字符串: || ':' || select 字段1 || ':' || 字段2 from table :字段1:字段2 3. ...
- LPC2478调试___ads常见错误分析
进行ADS外部RAM进行仿真调试过程中,出现常见错误“entry point lies outside the image" 原因为程序空间超出范围,需要修改一个参数. 解决方法:首先在Z ...
- Android基础
今天学习Android基本环境及基础知识,正确来说是重新温习Android知识,因为初次接触Android开发已经是两年前的事,如今又回到Android开发依然那么熟悉,依然可以让人很兴奋,Andro ...
- 《JavaScript高级程序设计》学习笔记(4)——引用类型
欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 本节内容对应<JavaScript高级程序设计>的第五章内容. 在ECMAScript中, ...