黑马程序员技术交流社区

标题: 【上海校区】spring源码系列7:Spring中的InstantiationAwareBeanPos... [打印本页]

作者: 梦缠绕的时候    时间: 2019-10-23 09:27
标题: 【上海校区】spring源码系列7:Spring中的InstantiationAwareBeanPos...
概念
Bean创建过程中的“实例化”与“初始化”名词
BeanPostProcessor :
发生在 BeanDefiniton 加工Bean 阶段. 具有拦截器的含义. 可以拦截BeanDefinition创建Bean的过程, 然后插入拦截方法,做扩展工作.
InstantiationAwareBeanPostProcessor: 继承于BeanPostProcessor ,所以他也是一种参与BeanDefinition加工Bean过程的BeanPostProcessor拦截器, 并且丰富了BeanPostProcessor的拦截.
总的来说:
BeanPostProcessor定义的方法是在对象初始化过程中做处理。
InstantiationAwareBeanPostProcessor定义的方法是在对象实例化过程中做处理
发生时机
1.postProcessBeforeInstantiation 调用时机
BeanDefinition创建Bean的开端是在createBean()方法也就是流水线的开始处。
        @Override    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {        ...省略        try {            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);            if (bean != null) {                return bean;            }        }        catch (Throwable ex) {            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,                    "BeanPostProcessor before instantiation of bean failed", ex);        }        Object beanInstance = doCreateBean(beanName, mbdToUse, args);        if (logger.isDebugEnabled()) {            logger.debug("Finished creating instance of bean '" + beanName + "'");        }        return beanInstance;    }
看这段英文注释: Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
给BeanPostProcessor一个机会去返回一个代理对象. 就是在流水线doCreateBean()生成对象之前, 给用户自定义返回一个对象的机会.
再看看resolveBeforeInstantiation(beanName, mbdToUse)是如何处理自定义返回对象的.
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {        Object bean = null;        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {            // Make sure bean class is actually resolved at this point.            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {                Class<?> targetType = determineTargetType(beanName, mbd);                if (targetType != null) {                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);                    if (bean != null) {                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);                    }                }            }            mbd.beforeInstantiationResolved = (bean != null);        }        return bean;    }
2.postProcessAfterInstantiation调用时机
上文resolveBeforeInstantiation()没有返回bean.则走流水线创建Bean
doCreateBean(beanName, mbdToUse, args)创建对象,会经过populateBean(beanName, mbd, instanceWrapper)方法。
populateBean(beanName, mbd, instanceWrapper)依次执行postProcessAfterInstantiation() postProcessPropertyValues()
3.postProcessBeforeInitialization调用时机
doCreateBean(beanName, mbdToUse, args)创建对象,会经过initializeBean(beanName, exposedObject, mbd);方法。
initializeBean(beanName, exposedObject, mbd); 会首先执行 postProcessBeforeInitialization()方法
4.postProcessAfterInitialization
initializeBean(beanName, exposedObject, mbd); 会首先执行 postProcessAfterInitialization()方法
总结:
实例化--->初始化
会形成两种执行流程完成BeanDefinition 创建Bean.
我们看出:postProcessBeforeInstantiation一定执行, postProcessAfterInitialization一定执行.
至此:不知道读者是否体会到了InstantiationAwareBeanPostProcessor与BeanPostProcessor接口 以及其定义的4个方法的妙处.


作者: 梦缠绕的时候    时间: 2019-10-23 09:27
有任何问题欢迎在评论区留言
作者: 梦缠绕的时候    时间: 2019-10-23 09:28
或者添加学姐微信
DKA-2018




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2