spring学习(二)--- bean的注册

    spring是通过IOC对bean进行管理的,而bean的初始化主要分为两部分:bean的注册和bean的实例化。bean的注册主要是spring通过读取配置文件获取各个bean的信息,并且对这些信息进行注册。spring中提供了BeanFactory对bean进行获取,但是其只是提供了一个简单的查询,真正的注册和管理是在BeanDefinitionRegistry中进行的,上节介绍的BeanDEfinition则是bean对应的信息。在分析其代码前,我们先看下使用到的类及其作用。

涉及的类

AliasRegistry

public interface AliasRegistry {

  //注册别名
   void registerAlias(String name, String alias);

  //删除别名
   void removeAlias(String alias);

 //判断
   boolean isAlias(String name);

 //获取所有别名
   String[] getAliases(String name);

}

   其实现类SimpleAliasRegistry使用map来进行管理,注册的实现逻辑如下:

public void registerAlias(String name, String alias) {
   Assert.hasText(name, "'name' must not be empty");
   Assert.hasText(alias, "'alias' must not be empty");
   synchronized (this.aliasMap) {
       //别名与真实名一致,无意义
      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);
      }
   }
}

BeanDefinitionRegistry

public interface BeanDefinitionRegistry extends AliasRegistry {

  // 注册 BeanDefinition
   void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
         throws BeanDefinitionStoreException;

  // 删除 BeanDefinition 
   void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

  // 获取 BeanDefinition 
   BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

   // 是否包含 BeanDefinition 
   boolean containsBeanDefinition(String beanName);

  // 获取所有 BeanDefinition 的名称
   String[] getBeanDefinitionNames();

  // 获取已经注册 BeanDefinition 的个数
   int getBeanDefinitionCount();

  // 该 BeanDefinition 是否已经在注册表中使用
   boolean isBeanNameInUse(String beanName);

}

    继承了AliasRegistry,定义了对BeanDefinition的操作

SingletonBeanRegistry

    定义了对单例bean的获取和注册,其中DefaultSingletonBeanRegistry是其一个实现,主要是通过集合对bean进行管理。使用的集合的属性名及作用:

  • singletonObjects:单例对象缓存,key-value:bean name --> bean instance 
  • singletonFactories:单例对应的工厂的缓存,使用工厂来创建单例,bean name --> ObjectFactory
  • earlySingletonObjects:之前的单例
  • registeredSingletons:以及注册过的单例
  • singletonsCurrentlyInCreation:正在创建的单例
  • inCreationCheckExclusions:在创建单例的时候,如果该单例正在创建,就不会再创建了,就应该排除掉,如果某个单例在该集合中,则表示该单例正在创建

    bean的注册:

public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
   Assert.notNull(beanName, "'beanName' 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);
   }
}

 

//主要是bean和对象通过map管理
protected void addSingleton(String beanName, Object singletonObject) {
   synchronized (this.singletonObjects) {
     //注册,如果单例对象为null,则使用 NULL_OBJECT 站位
      this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
      //该单例对象已经注册成功,则需要从工厂集合中移除,后面不需要再次注册
      this.singletonFactories.remove(beanName);
      //之前注册过的对象也移除
      this.earlySingletonObjects.remove(beanName);
      //向已经注册的单例集合中添加该实例
      this.registeredSingletons.add(beanName);
   }
}

    获取bean

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      //如果该单例没有注册过,且正在注册
      synchronized (this.singletonObjects) {
         singletonObject = this.earlySingletonObjects.get(beanName);
         if (singletonObject == null && allowEarlyReference) {
            //获取该bean对应的工厂,通过工厂了创建还bean
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               singletonObject = singletonFactory.getObject();
               this.earlySingletonObjects.put(beanName, singletonObject);
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

DefaultListableBeanFactory

    该类实现和继承了两种不同的接口和抽象类,一种是和注册相关的接口和抽象类,一种是和获取bean的接口。其注册bean的基本是先查是否已经注册过,如果注册过判断能否覆盖;没注册过,进行注册

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

   Assert.hasText(beanName, "Bean name must not be empty");
   Assert.notNull(beanDefinition, "BeanDefinition must not be null");

   if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
         //注册前端校验
         ((AbstractBeanDefinition) beanDefinition).validate();
      }
      catch (BeanDefinitionValidationException ex) {
         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
               "Validation of bean definition failed", ex);
      }
   }

   BeanDefinition oldBeanDefinition;

   oldBeanDefinition = this.beanDefinitionMap.get(beanName);
   if (oldBeanDefinition != null) {
      //已经注册
      if (!isAllowBeanDefinitionOverriding()) {
         //如果已经注册过该bean,且设置为不允许覆盖
         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
               "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
               "': There is already [" + oldBeanDefinition + "] bound.");
      }
      else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
         // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
         if (this.logger.isWarnEnabled()) {
            this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                  "' with a framework-generated bean definition: replacing [" +
                  oldBeanDefinition + "] with [" + beanDefinition + "]");
         }
      }
      else if (!beanDefinition.equals(oldBeanDefinition)) {
         if (this.logger.isInfoEnabled()) {
            this.logger.info("Overriding bean definition for bean '" + beanName +
                  "' with a different definition: replacing [" + oldBeanDefinition +
                  "] with [" + beanDefinition + "]");
         }
      }
      else {
         if (this.logger.isDebugEnabled()) {
            this.logger.debug("Overriding bean definition for bean '" + beanName +
                  "' with an equivalent definition: replacing [" + oldBeanDefinition +
                  "] with [" + beanDefinition + "]");
         }
      }
      //如果允许覆盖,则直接注册,覆盖
      this.beanDefinitionMap.put(beanName, beanDefinition);
   }
   else {
      if (hasBeanCreationStarted()) {
         // 该bean还没注册,检查该工厂的bean创建阶段是否已经开始
         synchronized (this.beanDefinitionMap) {
            this.beanDefinitionMap.put(beanName, beanDefinition);
            List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
            updatedDefinitions.addAll(this.beanDefinitionNames);
            updatedDefinitions.add(beanName);
            this.beanDefinitionNames = updatedDefinitions;
            if (this.manualSingletonNames.contains(beanName)) {
               Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
               updatedSingletons.remove(beanName);
               this.manualSingletonNames = updatedSingletons;
            }
         }
      }
      else {
         // 如果仍然在启动注册阶段,则直接注册
         this.beanDefinitionMap.put(beanName, beanDefinition);
         this.beanDefinitionNames.add(beanName);
         this.manualSingletonNames.remove(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }

   if (oldBeanDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
   }
}

bean的注册

    bean注册主要分为两个部分,一部分是读取配置文件信息到内存的Document,第二部分是对Document的节点进行解析注册。注册的逻辑主要在DefaultBeanDefinitionDocumentReader 中的parseBeanDefinitions方法中

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
   if (delegate.isDefaultNamespace(root)) {
      NodeList nl = root.getChildNodes();
      for (int i = 0; i < nl.getLength(); i++) {
         Node node = nl.item(i);
         if (node instanceof Element) {
            Element ele = (Element) node;
            if (delegate.isDefaultNamespace(ele)) {
              //解析默认的节点
               parseDefaultElement(ele, delegate);
            }
            else {
               //解析自定义节点
               delegate.parseCustomElement(ele);
            }
         }
      }
   }
   else {
      delegate.parseCustomElement(root);
   }
}

    spring的配置文件中,有两大类的bean的声明,一个是默认的<bean>,还有一种是自定义的声明,这里主要讲一下默认的<bean>的声明。

    在解析默认的节点的时候,主要是解析<import>、<alias>、<bean>和<beans>,主要看下是如何解析<bean>的。

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
   //解析获取bean的各种属性
   BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
   if (bdHolder != null) {
      //对自定义的标签进行解析
      bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
      try {
         // 注册
         BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
      }
      catch (BeanDefinitionStoreException ex) {
         getReaderContext().error("Failed to register bean definition with name '" +
               bdHolder.getBeanName() + "'", ele, ex);
      }
      // Send registration event.
      getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
   }
}

    当解析完bean的所有节点的属性,会得到一个BeanDefinitionHolder的对象,该对象包含了bean的所有的信息。

public static void registerBeanDefinition(
      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
      throws BeanDefinitionStoreException {

   // beanname
   String beanName = definitionHolder.getBeanName();
   //使用 DefaultListableBeanFactory 来注册bean,即把beanName和对应的BeanDefinition 注册到map中
   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

   // 注册别名,调用 SimpleAliasRegistry 的 registerAlias 来注册别名
   String[] aliases = definitionHolder.getAliases();
   if (aliases != null) {
      for (String alias : aliases) {
         registry.registerAlias(beanName, alias);
      }
   }
}

    至此,<bean>标签的注册分析完毕。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值