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的某些属性的元数据

  1. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  2. <property name="locations" value="classpath:com/something/jdbc.properties"/>
  3. </bean>
  4. <bean id="dataSource" destroy-method="close"
  5. class="org.apache.commons.dbcp.BasicDataSource">
  6. <property name="driverClassName" value="${jdbc.driverClassName}"/>
  7. <property name="url" value="${jdbc.url}"/>
  8. <property name="username" value="${jdbc.username}"/>
  9. <property name="password" value="${jdbc.password}"/>
  10. </bean>
  11. jdbc.driverClassName=org.hsqldb.jdbcDriver
  12. jdbc.url=jdbc:hsqldb:hsql://production:9002
  13. jdbc.username=sa
  14. jdbc.password=root

注:``PropertyPlaceholderConfigurer不仅在您指定的属性文件中查找属性。 默认情况下,如果它在指定的属性文件中找不到属性,它还会检查Java System属性

PropertyOverrideConfigurer

类似于PropertyPlaceholderConfigurer的bean工厂后置处理器。与PropertyPlaceholderConfigurer不同的是,PropertyOverrideConfigurer对于所有的bean属性,原始定义可以有默认值或也可能没有值。如果一个Properties覆盖文件没有配置特定的bean属性,则就会使用默认的上下文定义。
注意,bean定义是不知道是否被覆盖的,所以从XML定义文件中不能马上看到那个配置正在被使用。在拥有多个PropertyOverrideConfigurer 实例的情况下,为相同bean的属性定义不同的值时,基于覆盖机制只会有最后一个生效