Spring BeanFactoryPostProcessor和BeanPostProcessor详解 - TFdream/blog GitHub Wiki

BeanFactoryPostProcessor和BeanPostProcessor,这两个接口,都是Spring初始化bean时对外暴露的扩展点。两个接口名称看起来很相似,但作用及使用场景却不同。

1、BeanFactoryPostProcessor接口

public interface BeanFactoryPostProcessor {  
  
    /** 
     * Modify the application context's internal bean factory after its standard 
     * initialization. All bean definitions will have been loaded, but no beans 
     * will have been instantiated yet. This allows for overriding or adding 
     * properties even to eager-initializing beans. 
     * @param beanFactory the bean factory used by the application context 
     * @throws org.springframework.beans.BeansException in case of errors 
     */  
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;  
  
}

实现该接口,可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。

注意:BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的。

Spring中,有内置的一些BeanFactoryPostProcessor实现类,常用的有:

  • org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
  • org.springframework.beans.factory.config.PropertyOverrideConfigurer

2、BeanPostProcessor接口

public interface BeanPostProcessor {  
  
    /** 
     * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean 
     * initialization callbacks (like InitializingBean's <code>afterPropertiesSet</code> 
     * or a custom init-method). The bean will already be populated with property values. 
     * The returned bean instance may be a wrapper around the original. 
     * @param bean the new bean instance 
     * @param beanName the name of the bean 
     * @return the bean instance to use, either the original or a wrapped one 
     * @throws org.springframework.beans.BeansException in case of errors 
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet 
     */  
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;  
  
    /** 
     * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean 
     * initialization callbacks (like InitializingBean's <code>afterPropertiesSet</code> 
     * or a custom init-method). The bean will already be populated with property values. 
     * The returned bean instance may be a wrapper around the original. 
     * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean 
     * instance and the objects created by the FactoryBean (as of Spring 2.0). The 
     * post-processor can decide whether to apply to either the FactoryBean or created 
     * objects or both through corresponding <code>bean instanceof FactoryBean</code> checks. 
     * <p>This callback will also be invoked after a short-circuiting triggered by a 
     * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method, 
     * in contrast to all other BeanPostProcessor callbacks. 
     * @param bean the new bean instance 
     * @param beanName the name of the bean 
     * @return the bean instance to use, either the original or a wrapped one 
     * @throws org.springframework.beans.BeansException in case of errors 
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet 
     * @see org.springframework.beans.factory.FactoryBean 
     */  
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;  
  
}  

BeanPostProcessor,可以在Spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:

  • bean实现了InitializingBean接口,对应的方法为afterPropertiesSet
  • 在bean定义的时候,通过init-method设置的方法

注意: BeanPostProcessor是在spring容器加载了bean的定义文件并且实例化bean之后执行的。 BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后。

Spring中,有内置的一些BeanPostProcessor实现类,例如:

  • org.springframework.context.annotation.CommonAnnotationBeanPostProcessor:支持@Resource注解的注入
  • org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor:支持@Required注解的注入
  • org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor:支持@Autowired注解的注入
  • org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor:支持@PersistenceUnit和@PersistenceContext注解的注入
  • org.springframework.context.support.ApplicationContextAwareProcessor:用来为bean注入ApplicationContext等容器对象

这些注解类的BeanPostProcessor,在spring配置文件中,可以通过这样的配置 <context:component-scan base-package="*.*" /> ,自动进行注册(Spring通过ComponentScanBeanDefinitionParser类来解析该标签)。

⚠️ **GitHub.com Fallback** ⚠️