学习总结与分享-Spring IOC容器源码之扩展知识浅读

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初始化时调用初始化方法后进行自定义处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值