8.1.5 重写占位符配置器

8.1.5 重写占位符配置器

PropertyOverrideConfigurerSpring提供的另一个容器后处理器,这个后处理器的作用比上面那个容器后处理器的功能更加强大。
PropertyOverrideConfigurer的属性文件指定的信息可以直接覆盖Spring配置文件中的元数据。
如果PropertyOverrideConfigurer的属性文件指定了一些配置的元数据,则这些配置的元数据将会覆盖原配置文件里相应的数据。在这种情况下,可以认为Spring配置信息是XML配置文件和属性文件的总和,当XML配置文件和属性文件指定的元数据不一致时,以属性文件的信息为准。

使用PropertyOverrideConfigurer的属性文件,每条属性应保持如下的格式:
beanId.property=value
beanId是属性占位符试图覆盖的Beanid, property是试图覆盖的属性名(对应于调用setter方法)。

程序示例

1
2
3
4
5
6
7
E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\PropertyOverrideConfigurer
├─data.sql
└─src\
├─beans.xml
├─dbconn.properties
└─lee\
└─BeanTest.java

beans.xml

看如下配置文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- PropertyOverrideConfigurer是一个容器后处理器,它会读取
属性文件信息,并用这些信息设置覆盖Spring配置文件的数据 -->
<bean class=
"org.springframework.beans.factory.config.PropertyOverrideConfigurer">
<property name="locations">
<list>
<value>dbconn.properties</value>
<!-- 如果有多个属性文件,依次在下面列出来 -->
</list>
</property>
</bean>
<!-- 定义数据源Bean,使用C3P0数据源实现,
配置该Bean时没有指定任何信息,但Properties文件里的
信息将会直接覆盖该Bean的属性值 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"/>
</beans>

上面的配置文件中配置数据源Bean时,没有指定任何属性值,很明显配置数据源Bean时不指定有效信息是无法连接到数据库服务的。
但因为Spring容器中部署了一个PropertyOverrideConfigurer容器后处理器,而且Spring容器使用ApplicationContext作为容器,它会自动检测容器中的容器后处理器,并使用该容器后处理器来处理Spring容器。
PropertyOverride Configurer后处理器读取dbconn.properties文件中的属性,用于覆盖目标Bean的属性。因此,如果属性文件中有dataSourceBean属性的设置,则可在配置文件中为该Bean指定属性值,这些属性值将会覆盖dataSourceBean的各属性值。
dbconn.properties属性文件如下:

1
2
3
4
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://localhost:3306/spring?useSSL=true
dataSource.user=root
dataSource.password=root

属性文件里每条属性的格式必须是:
beanId.property=value
也就是说, dataSource必须是容器中真实存在的Beanid,否则程序将出错。
程序无法知道BeanFactory定义是否被覆盖。仅仅通过查看XML配置文件,无法知道配置文件的配置信息是否被覆盖。如有多个PorpertyOverrideConfigurer对同一Bean属性进行了覆盖,最后一次覆盖将会获胜。
对于采用基于XML Schema的配置文件而言,如果导入了contextSchema,则可采用如下方式来配置这种重写占位符。

使用context:property-override元素简化配置

1
<context: property-override location=classpath:db.properties"/>

也就是说,<context:property-override>元素是PorpertyOverrideConfigurer的简化配置。