bean工厂后置处理器
Spring IoC容器允许BeanFactoryPostProcessor
读取配置元数据(BeanDefinition), 并可能在容器实例化任何(除BeanFactoryPostProcessor
实例之外)bean之前更改元数据.
作用时间点
Spring容器完成bean定义(类信息)扫描,即类信息实体组装完成,但未进行实例化时。
处理器作用
- 解析Spring的配置类。利用此处理器可以修改bean定义实体信息。从而影响对应bean的实例化过程。
- 可以配置多个
BeanFactoryPostProcessor
实例,并且可以通过设置order
属性来控制这些BeanFactoryPostProcessor
实例的运行顺序(BeanFactoryPostProcessor
必须实现了Ordered
接口才能设置这个属性)。 如果编写自己的BeanFactoryPostProcessor,则应考虑实现Ordered接口 BeanFactoryPostProcessor
会在整个容器内起作用,所有它仅仅与正在使用的容器相关
注:
类信息:是否懒加载、类名、类的作用域、等
bean定义使用实体beanDefinition存放,会放入beanDefinitionMap归集,类名为key
并且全类名放入beanDefinitionNames(ArrayList)集合。
处理器发现
ApplicationContext
自动检测部署到Spring中的任何实现BeanFactoryPostProcessor
接口的bean,使用bean工厂后置处理器,可以对定义在容器中的元数据配置进行修改。
常用Bean工厂后置处理器
PropertyPlaceholderConfigurer
作用
通过使用PropertyPlaceholderConfigurer,可以使用标准Java Properties格式从单独文件中读取bean定义的外部化属性值。
如变更数据库URL和密码,而无需修改容器的主XML定义文件。
在运行时,PropertyPlaceholderConfigurer
应用于替换DataSource的某些属性的元数据
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:com/something/jdbc.properties"/>
</bean>
<bean id="dataSource" 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>
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root
注:``PropertyPlaceholderConfigurer
不仅在您指定的属性文件中查找属性。 默认情况下,如果它在指定的属性文件中找不到属性,它还会检查Java System
属性
PropertyOverrideConfigurer
类似于PropertyPlaceholderConfigurer的bean工厂后置处理器。与PropertyPlaceholderConfigurer不同的是,PropertyOverrideConfigurer对于所有的bean属性,原始定义可以有默认值或也可能没有值。如果一个Properties
覆盖文件没有配置特定的bean属性,则就会使用默认的上下文定义。
注意,bean定义是不知道是否被覆盖的,所以从XML定义文件中不能马上看到那个配置正在被使用。在拥有多个PropertyOverrideConfigurer 实例的情况下,为相同bean的属性定义不同的值时,基于覆盖机制只会有最后一个生效