账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    关于Spring IoC 源码有一处的疑问
    21
    0

    采纳了@代码宇宙 大大的答案。我自己具体的思考在我的答案里有给出。

    Spring IoC 在创建对象的时候,可以大致分为3步:

    • createBeanInstance() 实例化
    • populateBean() 属性装配
    • initializeBean() 处理Bean初始化之后的各种回调事件

    在阅读AbstractAutowireCapableBeanFactory#initializeBean() 源码的时候,

        protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        invokeAwareMethods(beanName, bean);
                        return null;
                    }
                }, getAccessControlContext());
            }
            else {
                // 涉及到的回调接口点进去一目了然,代码都是自解释的
                // BeanNameAware、BeanClassLoaderAware或BeanFactoryAware
                invokeAwareMethods(beanName, bean);
            }
    
            Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
                // BeanPostProcessor 的 postProcessBeforeInitialization 回调
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
    
            try {
                // init-methods
                // 或者是实现了InitializingBean接口,会调用afterPropertiesSet() 方法
                invokeInitMethods(beanName, wrappedBean, mbd);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(
                        (mbd != null ? mbd.getResourceDescription() : null),
                        beanName, "Invocation of init method failed", ex);
            }
            if (mbd == null || !mbd.isSynthetic()) {
                // BeanPostProcessor 的 postProcessAfterInitialization 回调
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
            return wrappedBean;
        }

    上面是我自己完成这部分源码阅读学习后的注释版本代码,大家发现没有,BeanPostProcessor 的两个回调都发生在这边,只不过中间处理了 init-method。

    这和我原来的认知有点不一样了?因为Spring的源码中代码的命名很多时候是自解释的,很多时候我看英文就知道这些方法的意图,但在这里,为什么BeanPostProcessor的前置处理方法postProcessBeforeInitialization()也是在属性设置完成后调用的?

    准确来说到这里已经是after initialization了,难道initialization代表的意思是调用init-method?这样好像能说的通。

    这个问题可能会被感觉有点钻牛角尖,但还想听听大家的见解。

    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 11 元积分
        全部回答
    • 0
    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部