BeanDefinitionHolder源码解析

继承关系

实现的接口

BeanDefinition一样实现了BeanMetadataElement接口,获得了获取数据源(配置类的class对象)的能力。

/**
 *  将由承载配置源对象的bean元数据元素实现的接口。
 */
public interface BeanMetadataElement {
   /**
    * 返回此元数据元素的配置源{@code  Object}(可以为{@code  null})。
    */
   @Nullable
   default Object getSource() {
      return null;
   }
}

本类解析

具有名称和别名的BeanDefinition的持有人。 可以注册为内部bean的占位符。 还可以用于内部bean定义的程序化注册。 如果您不关心BeanNameAware之类的东西,那么注册RootBeanDefinition或ChildBeanDefinition就足够了。


public class BeanDefinitionHolder implements BeanMetadataElement {
   /**
    * 要包含的BeanDefinition
    */
   private final BeanDefinition beanDefinition;
  /**
    * BeanDefinition对应的beanName
    */
   private final String beanName;
  /**
    * BeanDefinition对应的别名集合
    */
   @Nullable
   private final String[] aliases;

   /**
    * 创建一个新的BeanDefinitionHolder。
    * @param  beanDefinition 要包装的BeanDefinition
    * @param  beanName bean名称,为bean定义指定的名称
    */
   public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) {
      this(beanDefinition, beanName, null);
   }

   /**
    * 创建一个新的BeanDefinitionHolder。
    * @param  beanDefinition bean包装的BeanDefinition
    * @param  beanName 为bean定义指定的bean名称。
    * @param aliases bean的别名,或者{@code null}(如果没有)
    */
   public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, @Nullable String[] aliases) {
      Assert.notNull(beanDefinition, "BeanDefinition must not be null");
      Assert.notNull(beanName, "Bean name must not be null");
      this.beanDefinition = beanDefinition;
      this.beanName = beanName;
      this.aliases = aliases;
   }

   /**
    * 复制构造函数:创建一个新的BeanDefinitionHolder,其内容与给定的BeanDefinitionHolder实例相同。
    *  <p>注意:包装好的BeanDefinition引用按原样使用;
    *  这不是深度复制。
    * @param  beanDefinitionHolder 要复制的BeanDefinitionHolder
    */
   public BeanDefinitionHolder(BeanDefinitionHolder beanDefinitionHolder) {
      Assert.notNull(beanDefinitionHolder, "BeanDefinitionHolder must not be null");
      this.beanDefinition = beanDefinitionHolder.getBeanDefinition();
      this.beanName = beanDefinitionHolder.getBeanName();
      this.aliases = beanDefinitionHolder.getAliases();
   }

   /**
    * 返回包装的BeanDefinition。
    *
    */
   public BeanDefinition getBeanDefinition() {
      return this.beanDefinition;
   }

   /**
    * 返回为bean定义指定的bean的主要名称。
    *
    */
   public String getBeanName() {
      return this.beanName;
   }

   /**
    * 返回直接为bean定义指定的bean的别名。
    * @return 别名名称的数组;
    * 如果没有别名,则为{<@@code> null}
    */
   @Nullable
   public String[] getAliases() {
      return this.aliases;
   }

   /**
    * 公开bean定义的源对象。
    *
    * @see  BeanDefinition#getSource()
    */
   @Override
   @Nullable
   public Object getSource() {
      return this.beanDefinition.getSource();
   }

   /**
    * 确定给定的候选名称是否与Bean名称或此Bean定义中存储的别名匹配。
    */
   public boolean matchesName(@Nullable String candidateName) {
      return (candidateName != null && (candidateName.equals(this.beanName) ||
            candidateName.equals(BeanFactoryUtils.transformedBeanName(this.beanName)) ||
            ObjectUtils.containsElement(this.aliases, candidateName)));
   }

   /**
    * 返回该bean的友好简短描述,名称和别名。
    * @see  #getBeanName()
    * @see  #getAliases()
    */
   public String getShortDescription() {
      if (this.aliases == null) {
         return "Bean definition with name '" + this.beanName + "'";
      }
      return "Bean definition with name '" + this.beanName + "' and aliases [" + StringUtils.arrayToCommaDelimitedString(this.aliases) + ']';
   }

   /**
    * 返回该bean的详细描述,包括名称和别名,以及对包含的{@link  BeanDefinition}的描述。
    *
    * @see  #getShortDescription()
    * @see  #getBeanDefinition()
    */
   public String getLongDescription() {
      return getShortDescription() + ": " + this.beanDefinition;
   }

   /**
    * 此实现返回详细描述。
    * 可以重写以返回简短描述或任何类型的自定义描述。
    *
    * @see  #getLongDescription()
    * @see  #getShortDescription()
    */
   @Override
   public String toString() {
      return getLongDescription();
   }

   @Override
   public boolean equals(@Nullable Object other) {
      if (this == other) {
         return true;
      }
      if (!(other instanceof BeanDefinitionHolder)) {
         return false;
      }
      BeanDefinitionHolder otherHolder = (BeanDefinitionHolder) other;
      return this.beanDefinition.equals(otherHolder.beanDefinition) &&
            this.beanName.equals(otherHolder.beanName) &&
            ObjectUtils.nullSafeEquals(this.aliases, otherHolder.aliases);
   }

   @Override
   public int hashCode() {
      int hashCode = this.beanDefinition.hashCode();
      hashCode = 29 * hashCode + this.beanName.hashCode();
      hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.aliases);
      return hashCode;
   }

}

总结

BeanDefinitionHolder就是BeanDefinition + beanName + beanAlias的持有者。
疑问:

BeanNameAware是啥?

Spring BeanDefinitionHolder源码解析的更多相关文章

  1. Spring IoC源码解析之invokeBeanFactoryPostProcessors

    一.Bean工厂的后置处理器 Bean工厂的后置处理器:BeanFactoryPostProcessor(触发时机:bean定义注册之后bean实例化之前)和BeanDefinitionRegistr ...

  2. Spring系列(三):Spring IoC源码解析

    一.Spring容器类继承图 二.容器前期准备 IoC源码解析入口: /** * @desc: ioc原理解析 启动 * @author: toby * @date: 2019/7/22 22:20 ...

  3. spring事务源码解析

    前言 在spring jdbcTemplate 事务,各种诡异,包你醍醐灌顶!最后遗留了一个问题:spring是怎么样保证事务一致性的? 当然,spring事务内容挺多的,如果都要讲的话要花很长时间, ...

  4. Spring IoC源码解析之getBean

    一.实例化所有的非懒加载的单实例Bean 从org.springframework.context.support.AbstractApplicationContext#refresh方法开发,进入到 ...

  5. Spring系列(五):Spring AOP源码解析

    一.@EnableAspectJAutoProxy注解 在主配置类中添加@EnableAspectJAutoProxy注解,开启aop支持,那么@EnableAspectJAutoProxy到底做了什 ...

  6. Spring系列(六):Spring事务源码解析

    一.事务概述 1.1 什么是事务 事务是一组原子性的SQL查询,或者说是一个独立的工作单元.要么全部执行,要么全部不执行. 1.2 事务的特性(ACID) ①原子性(atomicity) 一个事务必须 ...

  7. Spring Boot系列(四):Spring Boot源码解析

    一.自动装配原理 之前博文已经讲过,@SpringBootApplication继承了@EnableAutoConfiguration,该注解导入了AutoConfigurationImport Se ...

  8. Spring Security源码解析一:UsernamePasswordAuthenticationFilter之登录流程

    一.前言 spring security安全框架作为spring系列组件中的一个,被广泛的运用在各项目中,那么spring security在程序中的工作流程是个什么样的呢,它是如何进行一系列的鉴权和 ...

  9. Spring IoC源码解析——Bean的创建和初始化

    Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...

随机推荐

  1. [RAC] 1. 安装Oracle RAC时,不能验证ASMSNMP密码问题的解决(ORA-01031或ORA-01017)

      1."ORA-01031: insufficient privileges" [grid@node1 bin]$ orapwd file=/u01/app/11.2.0/gri ...

  2. Golang import具体使用

    使用gopath的时候,一般引用是从src下一层开始,比如src/github.com/…,引用github.com…,我的工程src/xxx.com/go-qb/…,引用xxx.com/go-qb/ ...

  3. 《Redis5.x入门教程》正式推出

    关注公众号CoderBuff回复"redis"可抢先获取<Redis5.x入门教程>PDF完整版 在<ElasticSearch6.x实战教程>之后,又斗胆 ...

  4. 达梦数据库-RAC-DMDSC部署的关键点

    达梦数据库-RAC-DMDSC部署的关键点 环境准备 网络准备(ip地址分配).共享磁盘准备和挂载 ifconfig enp0s8 10.1.2.101;ifconfig enp0s9 192.168 ...

  5. 票据传递之MS14-068

    MS14-068是密钥分发中心(KDC)服务中的Windows漏洞.它允许经过身份验证的用户在其Kerberos票证(TGT)中插入任意PAC(表示所有用户权限的结构).该漏洞位于kdcsvc.dll ...

  6. spring cloud微服务快速教程之(十一) Sleuth(zipkin) 服务链路追踪

    0.前言 微服务架构上众多微服务通过REST调用,可能需要很多个服务协同才能完成一个接口功能,如果链路上任何一个服务出现问题或者网络超时,都会形成导致接口调用失败.随着业务的不断扩张,服务之间互相调用 ...

  7. Webpack中hash、chunkhash和contenthash三者的区别

    在webpack中有三种的方式生成哈希值,分别为hash.chunkhash和contenthash.这三种方式有着不同的用处,或者说在webpack的不同环境中,会使用不同的方式生成哈希值.那为什么 ...

  8. SQL Server 2019 表无法修改问题

    SQL Server 2019 表无法修改问题 问题描述: 解决方法: 1.在菜单栏中,点击工具->选项,示例: 2.在选项中单击设计器->表设计器和数据库设计器->取消勾选阻止保存 ...

  9. 面试官:你用过mysql哪些存储引擎,请分别展开介绍一下

    这是高级开发者面试时经常被问的问题.实际我们在平时的开发中,经常会遇到的,在用SQLyog等工具创建表时,就有一个引擎项要你去选.如下图: Mysql的存储引擎有这么多种,实际我们在平时用的最多的莫过 ...

  10. List泛型

    .Net自从2.0以后开始支持泛型. 泛型的作用:可以创建独立于被包含类型的类和方法.泛型类使用泛型类型,并可以根据需要使用特定的类型替换泛型类型.这就保证了类型安全性:如果某个类型不支持泛型类,编译 ...