spring源码(10)从缓存中获取到单例bean的后续操作(对FactoryBean的处理)

这里写图片描述

从缓存中获取到实例,doGetBean第一步就是对我们输入的name做了处理。

  1. 去除FactoryBean的修饰符,也就是name=”&a”,最终处理为name=”a”
  2. 取指定别名最终所指向的beanName

在从缓存中获取实例时,getSingleton(beanName),参数是已经处理的。我们知道如果想要获取FactoryBean getObject方法对应的实例,那么name需要加前缀&。所以通过getSingletom获取到的可能是FactoryBean实例。

getObjectForBeanInstance就是对以上的纠正。

总体流程图如下:
这里写图片描述

protected Object getObjectForBeanInstance(
                    Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

             //如果name的以&为开头,但是beanInstance又不是FactoryBean类型,则抛出BeanIsNotAFactoryException
             if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
                    throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
             }

             //如果beanInstance不是FactoryBean类型,或者不是以&开头,则直接返回实例
             if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
                    return beanInstance;
             }

             //以下步骤处理以&开头的name,即FactoryBean
             Object object = null;
             if (mbd == null) {
                    //尝试从缓存中加载bean
                    object = getCachedObjectForFactoryBean(beanName);
             }
             if (object == null) {
                    //到这里已经明确知道beanInstance为FactoryBean类型
                    FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
                    //将存储XML配置文件的GernericBeanDefinition转换成RootBeanDefinition
                    if (mbd == null && containsBeanDefinition(beanName)) {
                          mbd = getMergedLocalBeanDefinition(beanName);
                    }
                    boolean synthetic = (mbd != null && mbd.isSynthetic());

                    object = getObjectFromFactoryBean(factory, beanName, !synthetic);
             }
             return object;
       }
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
             //如果factoryBean为单例子,并且已经在缓存中存在
             if (factory.isSingleton() && containsSingleton(beanName)) {
                    //同步访问singletonObjects
                    synchronized (getSingletonMutex()) {
                          //从缓存中获取bean实例,如果存在直接返回
                          Object object = this.factoryBeanObjectCache.get(beanName);
                          if (object == null) {
                                 object = doGetObjectFromFactoryBean(factory, beanName);
                                 // Only post-process and store if not put there already during getObject() call above
                                 // (e.g. because of circular reference processing triggered by custom getBean calls)
                                 Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                                 if (alreadyThere != null) {
                                       object = alreadyThere;
                                 }
                                 else {
                                       if (object != null && shouldPostProcess) {
                                              try {
                                                    //后续处理
                                                    object = postProcessObjectFromFactoryBean(object, beanName);
                                              }
                                              catch (Throwable ex) {
                                                    throw new BeanCreationException(beanName,
                                                                  "Post-processing of FactoryBean's singleton object failed", ex);
                                              }
                                       }
                                       //加入缓存
                                        this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
                                 }
                          }
                          return (object != NULL_OBJECT ? object : null);
                    }
             }
             else {//如果不是单例
                    Object object = doGetObjectFromFactoryBean(factory, beanName);
                    if (object != null && shouldPostProcess) {
                          try {
                                 //后续处理
                                 object = postProcessObjectFromFactoryBean(object, beanName);
                          }
                          catch (Throwable ex) {
                                 throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                          }
                    }
                    return object;
             }
       }
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
                    throws BeanCreationException {

             Object object;
             try {
                    if (System.getSecurityManager() != null) {
                          AccessControlContext acc = getAccessControlContext();
                          try {
                                 object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                                       @Override
                                       public Object run() throws Exception {
                                                    return factory.getObject();
                                              }
                                       }, acc);
                          }
                          catch (PrivilegedActionException pae) {
                                 throw pae.getException();
                          }
                    }
                    else {
                          //直接调用factorybean的getObject方法
                          object = factory.getObject();
                    }
             }
             catch (FactoryBeanNotInitializedException ex) {
                    throw new BeanCurrentlyInCreationException(beanName, ex.toString());
             }
             catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
             }

             // Do not accept a null value for a FactoryBean that's not fully
             // initialized yet: Many FactoryBeans just return null then.
             if (object == null && isSingletonCurrentlyInCreation(beanName)) {
                    throw new BeanCurrentlyInCreationException(
                                 beanName, "FactoryBean which is currently in creation returned null from getObject");
             }
             return object;
       }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值