主要分析内容:
一、InstantiationAwareBeanPostProcessor简述与demo示例
二、InstantiationAwareBeanPostProcessor与BeanPostProcessor对比
三、InstantiationAwareBeanPostProcessor源码分析:注册时机和触发点
(源码基于spring 5.1.3.RELEASE分析)
一、InstantiationAwareBeanPostProcessor简述与demo示例
InstantiationAwareBeanPostProcessor继承自BeanPostProcessor 是spring非常重要的拓展接口,代表这bean的一段生命周期: 实例化(Instantiation)
1 public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { 2 3 @Nullable 4 default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { 5 return null; 6 } 7 8 default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { 9 return true; 10 } 11 12 @Nullable 13 default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) 14 throws BeansException { 15 16 return null; 17 } 18 19 @Deprecated 20 @Nullable 21 default PropertyValues postProcessPropertyValues( 22 PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { 23 24 return pvs; 25 } 26 27 }
由于InstantiationAwareBeanPostProcessor继承自BeanPostProcessor, 其他接口可以参考spring源码分析系列 (2) spring拓展接口BeanPostProcessor,这里针对多出接口说明一下:
1、postProcessBeforeInstantiation调用时机为bean实例化(Instantiation)之前 如果返回了bean实例, 则会替代原来正常通过target bean生成的bean的流程. 典型的例如aop返回proxy对象. 此时bean的执行流程将会缩短, 只会执行
BeanPostProcessor#postProcessAfterInitialization接口完成初始化。
2、postProcessAfterInstantiation调用时机为bean实例化(Instantiation)之后和任何初始化(Initialization)之前。
3、postProcessProperties调用时机为postProcessAfterInstantiation执行之后并返回true, 返回的PropertyValues将作用于给定bean属性赋值. spring 5.1之后出现以替换@Deprecated标注的postProcessPropertyValues
4、postProcessPropertyValues已经被标注@Deprecated,后续将会被postProcessProperties取代。
示例demo:
1 public class InstantiationAwareBeanPostProcessorTest { 2 private ApplicationContext applicationContext ; 3 4 @Before 5 public void beforeApplicationContext(){ 6 /** 7 * ApplicationContext 自动注册 BeanPostProcessor、InstantiationAwareBeanPostProcessor、BeanFactoryPostProcessor 8 * 不需要手动注册 9 * */ 10 applicationContext = new ClassPathXmlApplicationContext("ioc-InstantiationAwareBeanPostProcessor.xml") ; 11 } 12 13 @Test 14 public void test(){ 15 Bean bean = applicationContext.getBean("bean", Bean.class) ; 16 System.out.println(bean); 17 } 18 19 @After 20 public void after(){ 21 ((ClassPathXmlApplicationContext)applicationContext).close(); 22 } 23 }