Spring源码之FactoryBean的实现

在前面的文章Spring源码之IoC容器的Bean创建和依赖注入,DefaultListableBeanFactory容器为例中提到获取Bean的过程。

通过getBean方法调用doGetBean方法,如果从缓存中获得Bean,通过getObjectForBeanInstance方法完成FactoryBean的相关处理,取得FactoryBean的处理结果,也就是最终的Bean。

那么getObjectForBeanInstance方法做了哪些操作,一起看看

1、如果不是FactoryBean的调用(Bean的name如果以“&”开头,说明是想获得FactoryBean本身,或者缓存中获取到的Bean实例不是FactoryBean的子类),则结束处理返回beanInstance

2、以上说明getBean不是为了获取FactoryBean本身,并且缓存中获取到的Bean实例是FactoryBean的子类,这时候通过getObjectFromFactoryBean从FactoryBean中得到Bean

3、在doGetObjectFromFactoryBean方法中,调用factory的getObject方法来从FactoryBean中得到Bean

4、这里返回的是作为工厂的FactoryBean的生产的产品,而不是FactoryBean本身。

beanInstance如果实现了FactoryBean接口,那么根据该Bean的名称获取到的实际上是getObject()返回的对象,而不是这个Bean自身实例,如果要获取这个Bean自身实例,那么需要在名称前面加上’&'符号。

getObjectForBeanInstance方法

   protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
        if (BeanFactoryUtils.isFactoryDereference(name)) {
            if (beanInstance instanceof NullBean) {
                return beanInstance;
            } else if (!(beanInstance instanceof FactoryBean)) {
                throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
            } else {
                if (mbd != null) {
                    mbd.isFactoryBean = true;
                }

                return beanInstance;
            }
        } else if (!(beanInstance instanceof FactoryBean)) {
            return beanInstance;
        } else {
            Object object = null;
            if (mbd != null) {
                mbd.isFactoryBean = true;
            } else {
                object = this.getCachedObjectForFactoryBean(beanName);
            }

            if (object == null) {
                FactoryBean<?> factory = (FactoryBean)beanInstance;
                if (mbd == null && this.containsBeanDefinition(beanName)) {
                    mbd = this.getMergedLocalBeanDefinition(beanName);
                }

                boolean synthetic = mbd != null && mbd.isSynthetic();
                object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
            }

            return object;
        }
    }

getObjectFromFactoryBean方法

    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        if (factory.isSingleton() && this.containsSingleton(beanName)) {
            synchronized(this.getSingletonMutex()) {
                Object object = this.factoryBeanObjectCache.get(beanName);
                if (object == null) {
                    object = this.doGetObjectFromFactoryBean(factory, beanName);
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    } else {
                        if (shouldPostProcess) {
                            if (this.isSingletonCurrentlyInCreation(beanName)) {
                                return object;
                            }

                            this.beforeSingletonCreation(beanName);

                            try {
                                object = this.postProcessObjectFromFactoryBean(object, beanName);
                            } catch (Throwable var14) {
                                throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", var14);
                            } finally {
                                this.afterSingletonCreation(beanName);
                            }
                        }

                        if (this.containsSingleton(beanName)) {
                            this.factoryBeanObjectCache.put(beanName, object);
                        }
                    }
                }

                return object;
            }
        } else {
            Object object = this.doGetObjectFromFactoryBean(factory, beanName);
            if (shouldPostProcess) {
                try {
                    object = this.postProcessObjectFromFactoryBean(object, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", var17);
                }
            }

            return object;
        }
    }

doGetObjectFromFactoryBean方法

    private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
        Object object;
        try {
            if (System.getSecurityManager() != null) {
                AccessControlContext acc = this.getAccessControlContext();

                try {
                    object = AccessController.doPrivileged(factory::getObject, acc);
                } catch (PrivilegedActionException var6) {
                    throw var6.getException();
                }
            } else {
                object = factory.getObject();
            }
        } catch (FactoryBeanNotInitializedException var7) {
            throw new BeanCurrentlyInCreationException(beanName, var7.toString());
        } catch (Throwable var8) {
            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", var8);
        }

        if (object == null) {
            if (this.isSingletonCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
            }

            object = new NullBean();
        }

        return object;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值