Spring 框架提供了几种 PostProcessor接口用于建模对容器或者bean的后置处理器,它们定义了一些方法,这些方法在特定的时机会被调用。通过这种机制,框架自身或者应用开发人员有机会在不侵入容器或者bean核心逻辑的情况下为容器或者bean做针对某些特定方面的定制或者扩展:能力增强,属性设置,内容修改,对象代理,甚至直接替换整个bean。Spring 提供的 PostProcessor 接口有如下几种 :
BeanDefinitionRegistryPostProcessor– BeanDefinitionRegistry后置处理器 – 容器级别
BeanFactoryPostProcessor–BeanFactory后置处理器 – 容器级别
BeanPostProcessor–Bean后置处理器 – bean实例级别
实际应用中又可细分为如下几类 :
1. InstantiationAwareBeanPostProcessor
2. MergedBeanDefinitionPostProcessor
3. DestructionAwareBeanPostProcessor
4. SmartInstantiationAwareBeanPostProcessor
5. 一般BeanPostProcessor
Spring框架自身提供了很多这些PostProcessor的实现类,每个PostProcessor实现类分别有不同的关注点,Spring利用这些PostProcessor实现类完成了很多框架自身的任务,主要在容器启动和bean获取阶段。另外,开发人员也可以实现自己的PostProcessor来扩展Spring容器或者bean的能力。这里面尤其是通过自定义实现BeanPostProcessor,开发人员有机会对容器中所有的bean做定制。
BeanPostProcessor:
顾名思义, BeanPostProcessor定义了关于Bean的PostProcessor。这里的Bean就是我们一般意义上所说的bean容器中的bean实例了。
Spring容器在每个bean实例创建过程中bean实例初始化前后调用接口BeanPostProcessor定义的方法。
BeanPostProcessor接口定义了两个方法:
Object postProcessBeforeInitialization(Object bean, String beanName)
Object postProcessAfterInitialization(Object bean, String beanName)
上图中的bean初始化指的是以下几种情况 :
通过InitializingBean接口实现的afterPropertiesSet()方法;
xml方式指定的bean的 init-method 初始化方法;
JSR-250 注解 @PostConstruct 注解的初始化方法;
Java 配置类中 @Bean(initMethod = “init”) 指定的初始化方法;
/**
*
* 对新的bean实例进行订制化修改的factory hook。
* ApplicationContexts can autodetect BeanPostProcessor beans in their
* bean definitions and apply them to any beans subsequently created.
*
* 应用程序上下文ApplicationContext能够从自己的bean定义中自动检测BeanPostProcessor bean,
* 并随后在任意bean创建时应用到新创建的bean。
*
* @author Juergen Hoeller
* @since 10.10.2003
* @see InstantiationAwareBeanPostProcessor
* @see DestructionAwareBeanPostProcessor
* @see ConfigurableBeanFactory#addBeanPostProcessor
* @see BeanFactoryPostProcessor
*/
public interface BeanPostProcessor {
/**
* @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;
* if null, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* 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 bean instanceof FactoryBean checks.
*
* This callback will also be invoked after a short-circuiting triggered by a
* 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;
* if null, no subsequent BeanPostProcessors will be invoked
* @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;
}
BeanFactoryPostProcessor:
顾名思义,BeanFactoryPostProcessor定义了关于 BeanFactory 的PostProcessor。这里的BeanFactory其实就是一般常说的Spring bean 容器,通常是一个DefaultListableBeanFactory,它实现了BeanDefinitionRegistry接口用于作为bean定义注册表,同时也实现了接口ConfigurableListableBeanFactory用于作为一个bean容器。
执行时机 : 在BeanFactory的标准初始化之后并且所有的BeanDefinitionRegistryPostProcessor执行之后,此时所有的bean定义已经加载但是bean实例尚未创建。
/**
* Allows for custom modification of an application context's bean definitions,
* adapting the bean property values of the context's underlying bean factory.
*
* 1. 允许对上下文的bean定义做定制化修改;
* 2. 调整上下文内部bean factory中bean的属性值;
*
* Application contexts can auto-detect BeanFactoryPostProcessor beans in
* their bean definitions and apply them before any other beans get created.
*
* 应用上下文能够从它的bean定义中自动检测BeanFactoryPostProcessor bean,并在其他任何
* bean创建之前应用这些BeanFactoryPostProcessor。
*
* Useful for custom config files targeted at system administrators that
* override bean properties configured in the application context.
*
* See PropertyResourceConfigurer and its concrete implementations
* for out-of-the-box solutions that address such configuration needs.
*
* A BeanFactoryPostProcessor may interact with and modify bean
* definitions, but never bean instances. Doing so may cause premature bean
* instantiation, violating the container and causing unintended side-effects.
* If bean instance interaction is required, consider implementing
* BeanPostProcessor instead.
*
* BeanFactoryPostProcessor操作bean定义上而不是bean实例。
* 如果需要操作bean实例,考虑实现BeanPostProcessor接口。
*
* @author Juergen Hoeller
* @since 06.07.2003
* @see BeanPostProcessor
* @see PropertyResourceConfigurer
*/
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization.
*
* 在bean factory标准初始化之后对其进行修改。
*
* All bean definitions will have been loaded, but no beans
* will have been instantiated yet.
*
* 此时所有bean定义已经被加载,但是还没有bean被实例化。
*
* This allows for overriding or adding properties even to eager-initializing beans.
*
* 对bean的属性进行重写或者增加修改,甚至对eager-initializing bean也生效。
*
* @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;
}
BeanDefinitionRegistryPostProcessor:
顾名思义,BeanDefinitionRegistryPostProcessor定义了关于BeanDefinitionRegistry 的 PostProcessor 。这里的BeanDefinitionRegistry其实就是一般常说的Spring bean 容器,通常是一个DefaultListableBeanFactory,它实现了BeanDefinitionRegistry接口用于作为bean定义注册表,同时也实现了接口ConfigurableListableBeanFactory用于作为一个bean容器。
执行时机 : 在BeanDefinitionRegistry的标准初始化之后所有其他一般的BeanFactoryPostProcessor执行之前执行,此时所有的bean定义已经加载但是还没有bean实例被创建。
BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor, 可以在一般BeanFactoryPostProcessor调用之前对BeanDefinition做一些操作, 尤其是它可以注册用来生成BeanFactoryPostProcessor的bean定义。
/**
* Extension to the standard BeanFactoryPostProcessor SPI, allowing for
* the registration of further bean definitions before regular
* BeanFactoryPostProcessor detection kicks in. In particular,
* BeanDefinitionRegistryPostProcessor may register further bean definitions
* which in turn define BeanFactoryPostProcessor instances.
*
* 标准BeanFactoryPostProcessor SPI的扩展,允许在常规BeanFactoryPostProcessor 检测
* 开始前注册更多的bean定义。尤其值得一提的是,BeanDefinitionRegistryPostProcessor
* 甚至可以注册用来定义BeanFactoryPostProcessor实例的bean定义。
*
* 注意:该接口继承了另外一个接口 BeanFactoryPostProcessor
*
* @作者 Juergen Hoeller
* @开始版本 3.0.1
* @参考 org.springframework.context.annotation.ConfigurationClassPostProcessor
*/
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization.
* 在应用上下文内部的bean definition registry的标准初始化之后修改对其进行修改。
*
* All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet.
*
* 此时所有常规的bean定义已经被加载,但是还没有bean被实例化。
*
* This allows for adding further
* bean definitions before the next post-processing phase kicks in.
*
* 这样可以在下一阶段post-processing触发之前增加更多的bean定义。
*
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
BeanPostProcessor接口提供了两个供开发者自定义的方法:postProcessBeforeInitialization、postProcessAfterInitialization。
postProcessBeforeInitialization:该方法主要针对spring在bean初始化时调用初始化方法前进行自定义处理。
postProcessAfterInitialization:该方法主要针对spring在bean初始化时调用初始化方法后进行自定义处理。