Spring提供了一种叫做BeanFactoryPostProcessor的容器扩展机制。该机制允许我们在容器实例化相应对象之前,对注册到容器的BeanDefinition所保存的信息做相应的修改。这就相当于在容器实现的第一阶段最后加入一道工序,让我们对最终的BeanDefinition做一些额外的操作,比如修改其中bean定义的某些属性,为bean定义增加其他信息等。如果要自定义实现BeanFactoryPostProcessor,通常我们需要实现org.springframework.beans.factory.config.BeanFactoryPostProcessor接口。
常用的BeanFactoryPostProcessor的实现类
1.PropertyPlaceholderConfigurer
PropertyPlaceholderConfigurer允许我们在XML配置文件中使用占位符(PlaceHolder),并将这些占位符所代表的资源单独配置到简单的properties文件中来加载。以数据源的配置为例,使用了PropertyPlaceholderConfigurer之后(这里沿用代码清单4-42的配置内容),可以在XML配置文件中按照代码清单4-43所示的方式配置数据源,而不用将连接地址、用户名和密码等都配置到XML中。
实例:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="url"> <value>${jdbc.url}</value> </property> <property name="driverClassName"> <value>${jdbc.driver}</value> </property> <property name="username"> <value>${jdbc.username}</value> </property> <property name="password"> <value>${jdbc.password}</value> </property> <property name="testOnBorrow"> <value>true</value> </property> <property name="testOnReturn"> <value>true</value> </property> <property name="testWhileIdle"> <value>true</value> </property> </bean>
2.PropertyOverrideConfigurer
可以通过PropertyOverrideConfigurer对容器中配置的任何你想处理的bean定义的property信息进行覆盖替换。这听起来比较抽象,我们还是给个例子吧!比如之前的dataSource定义中,maxActive的值为100,如果我们觉得100不合适,那么可以通过PropertyOverrideConfigurer在其相应的properties文件中做如下所示配置,把100这个值给覆盖掉,如将其配置为200:
spring 配置文件
<bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"> <property name="location" value="pool-adjustment.properties"/> </bean>
pool-adjustment.properties文件信息
# pool-adjustment.properties 11
dataSource.minEvictableIdleTimeMillis=1000
dataSource.maxActive=50
(注释:properties文件内容格式必须是 beanName.propertyName=value )
3、CustomEditorConfigurer
XML所记载的,都是String类型,即容器从XML格式的文件中读取的都是字符串形式,最终应用程序却是由各种类型的对象所构成。要想完成这种由字符串到具体对象的转换(不管这个转换工作最终由谁来做),都需要这种转换规则相关的信息,而CustomEditorConfigurer就是帮助我们传达类似信息的。
3.1就是给出一个org.springframe.PropertyEditorRegistrar的实现。
public class DatePropertyEditorRegistrar implements PropertyEditorRegistrar { private PropertyEditor propertyEditor; public void registerCustomEditors(PropertyEditorRegistry peRegistry) { peRegistry.registerCustomEditor(java.util.Date.class, getPropertyEditor()); } public PropertyEditor getPropertyEditor(){ return propertyEditor; }
public void setPropertyEditor(PropertyEditor propertyEditor){
this.propertyEditor = propertyEditor;
}
spring 配置
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="propertyEditorRegistrars"> <list> <ref bean="datePropertyEditorRegistrar"/> </list> </property> </bean> <bean id="datePropertyEditorRegistrar" class="....DatePropertyEditorRegistrar"> <property name="propertyEditor"> <ref bean="datePropertyEditor" /> </property> </bean> <bean id="datePropertyEditor" class="....DatePropertyEditor"> <property name="datePattern"> <value>yyyy/MM/dd</value> </property> </bean>