Spring源码解读--DefaultSingletonBeanRegistry解读

首先看接口的关系:

     

    AliasRegistry 即Bean对应的别名,直接看其实现类的关系:

         

  可以看到是用一个并发Map来存储对应的关系:

   

而关于其的方法,可以看主要的两个方法,即RegisterAlias与getAlias:

     首先看RegisterAlias:

         

public void registerAlias(String name, String alias) {
   Assert.hasText(name, "'name' must not be empty");
   Assert.hasText(alias, "'alias' must not be empty");
    //如果alias对于beanName则直接删除原来的,也就是如果原来有存b->a,现在存b->b,
      则直接删除a->b,并且a->a也保存

   if (alias.equals(name)) {
      this.aliasMap.remove(alias);
   }
   else {
      String registeredName = this.aliasMap.get(alias);
      if (registeredName != null) {
         if (registeredName.equals(name)) {
            // An existing alias - no need to re-register
            return;
         }
         if (!allowAliasOverriding()) {
            throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
                  name + "': It is already registered for name '" + registeredName + "'.");
         }
      }
      checkForAliasCircle(name, alias);
      this.aliasMap.put(alias, name);
   }
}

然后上面checkForAliasCircle,即循环检查,

  这里应该从getAliases说起了:

     

public String[] getAliases(String name) {
   List<String> result = new ArrayList<>();
   synchronized (this.aliasMap) {
      retrieveAliases(name, result);
   }
   return StringUtils.toStringArray(result);
}

   这里又有一个自循环:

private void retrieveAliases(String name, List<String> result) {
   this.aliasMap.forEach((alias, registeredName) -> {
      if (registeredName.equals(name)) {
         result.add(alias);
         retrieveAliases(alias, result);
      }
   });
}

即首先通过BeanName获取其别名,再以别名Alias为BeanName获取其别名,()如下:

     

由此可见,其需要进行循环检查,不然就会进入死循环:

    

   

之后再看接口SingletonBeanRegistry:

    

 

之后即类DefaultSingletonBeanRegistry:

   

     关键是对这些全局变量的操作:

         我们结合具体代码来说明这些全局变量:

           首先:registerSingleton(String beanName, Object singletonObject);

      

public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
   Assert.notNull(beanName, "Bean name must not be null");
   Assert.notNull(singletonObject, "Singleton object must not be null");
   synchronized (this.singletonObjects) {
      Object oldObject = this.singletonObjects.get(beanName);
      if (oldObject != null) {
         throw new IllegalStateException("Could not register object [" + singletonObject +
               "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
      }
      addSingleton(beanName, singletonObject);
   }
}

进入addSingleton方法:

            

protected void addSingleton(String beanName, Object singletonObject) {
   synchronized (this.singletonObjects) {
      this.singletonObjects.put(beanName, singletonObject);
      this.singletonFactories.remove(beanName);
      this.earlySingletonObjects.remove(beanName);
      this.registeredSingletons.add(beanName);
   }
}

这里涉及到四个全局变量:通过代码可以看到在这里是将一个单例对象singletonObject条件到singletonObjects、registeredSingletons里,这个registeredSingletons通过名字我们可以知道,其就是已经注册过的Bean对象了。但是在这里你们是否有发现一个问题,为什么要用一个registeredSingletons去标识已注册Bean对象,也可以用singletonObjects啊?这里我们可以看有哪些地方有用到这个registeredSingletons(将bean对象添加到singletonObjects只有这里有添加),其中一处使用的地方就是我们刚才说的,还有一处就是:

    

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(singletonFactory, "Singleton factory must not be null");
   synchronized (this.singletonObjects) {
      if (!this.singletonObjects.containsKey(beanName)) {
         this.singletonFactories.put(beanName, singletonFactory);
         this.earlySingletonObjects.remove(beanName);
         this.registeredSingletons.add(beanName);
      }
   }
}

这里我们可以看到是将一个singletonFactories添加到singletonFactories中,同时添加到registeredSingletons中,这里我们应该

    可以知道表示已注册的Bean应该有两条线去标识它,即添加singletonObject与singletonFactory时,但其实我们正常创建一个bean它是先添加到singletonFactories里面去的,同时添加到registeredSingletons里,之后会在addSingleton(String beanName, Object singletonObject)再添加一次到registeredSingletons里,不过这次会失败:

   先调用addSingletonFactory方法添加,

     

之后会再调用一次addSingleton

那spring为什么会这样多此一举的设计呢?

    

public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
   Assert.notNull(beanName, "Bean name must not be null");
   Assert.notNull(singletonObject, "Singleton object must not be null");
   synchronized (this.singletonObjects) {
      Object oldObject = this.singletonObjects.get(beanName);
      if (oldObject != null) {
         throw new IllegalStateException("Could not register object [" + singletonObject +
               "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
      }
      addSingleton(beanName, singletonObject);
   }
}

   我们可以点这个方法看它有哪些方法调用它,我们发现在这个直接添加singletonObject会将spring自己的类添加进去,如:

            

所以可以知道,registeredSingletons与singletonObjects区别,一个是这个Spring容器的所有单例Bena,而另一个是我们注入的Bean。

   之后我们将目光用到另一个全局变量上:earlySingletonObjects,关于这个我们需要直接跳到DefaultSingletonBeanRegistry的父类AbstractAutowireCapableBeanFactory,看bean实例的创建

doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args){方法中有局部变量earlySingletonExposure:
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
      isSingletonCurrentlyInCreation(beanName));

可以看到它的值是有三个决定的,即是不是单例,允不允许循环调用、还有是不是这个bean正在创建中,可以看我的这篇博客:https://blog.csdn.net/qq_25179481/article/details/89241914

这个isSingletonCurrentlyInCreation是DefaultSingletonBeanRegistry的方法:

public boolean isSingletonCurrentlyInCreation(String beanName) {
   return this.singletonsCurrentlyInCreation.contains(beanName);
}

这里可以看到在方法

getSingleton(String beanName, ObjectFactory<?> singletonFactory)中是先将:

创建bean对象时先将其加入到:

beforeSingletonCreation(beanName);中

再调用singletonObject = singletonFactory.getObject();

singletonFactory去创建,在这里singletonFactory.getObject();可能就有循环调用了,因为需要完成singletonFactory.getObject();才会调用下一步:

   

finally {
   if (recordSuppressedExceptions) {
      this.suppressedExceptions = null;
   }
   afterSingletonCreation(beanName);
}

将其从全局变量singletonsCurrentlyInCreation清掉表明完成创建:

   

protected void afterSingletonCreation(String beanName) {
   if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
      throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
   }
}

    所以在变量:boolean earlySingletonExposure,如果有循环调用:

   

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
      isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
   if (logger.isDebugEnabled()) {
      logger.debug("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
   }
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

需要提前将这个ObjectFactory

初始化的还没有进行任何赋值的空对象暴露到:

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(singletonFactory, "Singleton factory must not be null");
   synchronized (this.singletonObjects) {
      if (!this.singletonObjects.containsKey(beanName)) {
         this.singletonFactories.put(beanName, singletonFactory);
         this.earlySingletonObjects.remove(beanName);
         this.registeredSingletons.add(beanName);
      }
   }
}

  同时我们可以看到在 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));后就会:

if (earlySingletonExposure) {
   if (logger.isDebugEnabled()) {
      logger.debug("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
   }
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
   populateBean(beanName, mbd, instanceWrapper);
   exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
   if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
      throw (BeanCreationException) ex;
   }
   else {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
   }
}

if (earlySingletonExposure) {
   Object earlySingletonReference = getSingleton(beanName, false);

    通过populateBean(beanName, mbd, instanceWrapper);去给循环的Bean赋值,然后就会来到最开始的AbstractBeanFactory

:  

@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}

   

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

   final String beanName = transformedBeanName(name);
   Object bean;

   // Eagerly check singleton cache for manually registered singletons.
   Object sharedInstance = getSingleton(beanName);

                    ....................

在这里就会将前面的addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

       的ObjectFactory的内容创建暴露到earlySingletonObjects:

synchronized (this.singletonObjects) {
   singletonObject = this.earlySingletonObjects.get(beanName);
   if (singletonObject == null && allowEarlyReference) {
      ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
      if (singletonFactory != null) {
         singletonObject = singletonFactory.getObject();
         this.earlySingletonObjects.put(beanName, singletonObject);
         this.singletonFactories.remove(beanName);
      }
   }
}

以上这些操作,其实都是AbstractBeanFactory的:

   

public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}

     然后在doGetBean里的:

if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> {
      try {
         return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
         // Explicitly remove instance from singleton cache: It might have been put there
         // eagerly by the creation process, to allow for circular reference resolution.
         // Also remove any beans that received a temporary reference to the bean.
         destroySingleton(beanName);
         throw ex;
      }
   });
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
};

这个getSingleton(beanName, () -> {其实就是DefaultSingletonBeanRegistry的

getSingleton(String beanName, ObjectFactory<?> singletonFactory) ;

      

而return createBean(beanName, mbd, args);,就是singletonObject = singletonFactory.getObject();获取bean并赋值的过程,

   现在赋值完成后,就通过addSingleton(beanName, singletonObject);,将其暴露到singletonObjects里,这个时候就真正完成了一个Bean的创建于赋值了。

if (newSingleton) {
   addSingleton(beanName, singletonObject);
}

DefaultSingletonBeanRegistry的getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法摘要:
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
   this.suppressedExceptions = new LinkedHashSet<>();
}
try {
   singletonObject = singletonFactory.getObject();
   newSingleton = true;
}
catch (IllegalStateException ex) {
   // Has the singleton object implicitly appeared in the meantime ->
   // if yes, proceed with it since the exception indicates that state.
   singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null) {
      throw ex;
   }
}
catch (BeanCreationException ex) {
   if (recordSuppressedExceptions) {
      for (Exception suppressedException : this.suppressedExceptions) {
         ex.addRelatedCause(suppressedException);
      }
   }
   throw ex;
}
finally {
   if (recordSuppressedExceptions) {
      this.suppressedExceptions = null;
   }
   afterSingletonCreation(beanName);
}
if (newSingleton) {
   addSingleton(beanName, singletonObject);
}

 

     自此DefaultSingletonBeanRegistry的几个关键的全局变量,就梳理完毕,而其他的关于DependentBean的全局变量,到时候在写下这篇的下部分。个人感觉,对于spring的总流程来说,这个DependentBean的流程,应该没怎么复杂,也不算是构建spring很核心部分的内容,所以不会在这一篇的后面,之后有时间,通过测试demo简单说明一下吧。

 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值