BeanDefinition

继承图

继承的接口

BeanMetadataElement接口

将由承载配置源对象的bean元数据元素的类实现。

包含一个getSource的方法,可以获取到MetaData对应的配置类的类对象(class对象)。

public interface BeanMetadataElement
    /**
     * 返回此元数据元素的配置源{@code  Object}(可以为{@code  null})。
     * 如要配置的Bean类是A,那么getSource返回A.class
     */
    @Nullable
    default Object getSource() {
        return null;
    }
}
AttributeAccessor接口

定义用于 将metadata附加到任意对象 或 从任意对象访问metadata 的通用协定的接口。

包含设置属性、添加属性、获得属性等方法。


public interface AttributeAccessor {

   /**
    * 将{@code  name}定义的属性设置为提供的{@code  value}。
    * 如果{@code  value}为{@code  null},则属性为{@link  #removeAttribute remove}。
    *  <p>通常,用户应注意通过使用完全限定的名称(可能使用类或程序包名称作为前缀)来防止与其他元数据属性重叠。
    * @param name 命名唯一属性键
    * @param value 要附加的属性值
    */
   void setAttribute(String name, @Nullable Object value);

   /**
    * 获取由{@code  name}标识的属性的值。
    * 如果属性不存在,则返回{@code  null}。
    * @param 命名唯一属性键
    * @return 属性的当前值(如果有)
    */
   @Nullable
   Object getAttribute(String name);

   /**
    * 删除由{@code  name}标识的属性,并返回其值。
    * 如果未找到{@code  name}下的属性,则返回{@code  null}。
    *
    * @param name 命名唯一属性键
    * @return 属性的最后一个值(如果有)
    */
   @Nullable
   Object removeAttribute(String name);

    /**
     * 如果由{@code  name}标识的属性存在,则返回{@code  true}。
     * 否则,返回{@code  false}。
     *
     * @param name 命名唯一属性键
     */
    boolean hasAttribute(String name);

   /**
    * 返回所有属性的名称。
    */
   String[] attributeNames();
}

新增属性和方法

BeanDefinition描述了一个bean实例,该实例具有属性值,构造函数参数值以及具体实现所提供的更多信息。 这只是一个最小的接口:主要目的是允许{@link BeanFactoryPostProcessor}自省和修改属性值和其他bean元数据。

主要定义了几种bean角色常量。包含对ParentNameBeanClassNameScope、属性、构造函数参数列表、依赖的bean、是否是单例类、是否是LazyInit、工厂方法、init方法、destory方法等的存取,其实就是将Bean的定义信息存储到这个BeanDefinition相应的属性中,后面对Bean的操作就根据BeanDefinition进行,例如拿到这个BeanDefinition后,可以根据里面的类名、构造函数、构造函数参数,使用反射进行对象创建。

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

   /**
    * 标准单例作用域的作用域标识符:{@value}。
    *  <p>请注意,扩展的bean工厂可能支持更多范围。
    *
    * @see  #setScope
    * @see  ConfigurableBeanFactory#SCOPE_SINGLETON
    */
   String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

   /**
    * 标准原型范围的范围标识符:{@value}。
    *  <p>请注意,扩展的bean工厂可能支持更多范围。
    *
    * @see  #setScope
    * @see  ConfigurableBeanFactory#SCOPE_PROTOTYPE
    */
   String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

   /**
    * 角色提示,指示{@code  BeanDefinition}是应用程序的主要部分。
    * 通常对应于用户定义的bean。
    */
   int ROLE_APPLICATION = 0;

   /**
    * 角色提示,指示{@code  BeanDefinition}是某些较大配置的支持部分,通常是外部{@link  org.springframework.beans.factory.parsing.ComponentDefinition}。
    *  {@code  SUPPORT} bean被认为很重要,足以在更仔细地查看特定的{@link  org.springframework.beans.factory.parsing.ComponentDefinition}时要注意,但在查看Bean的整体配置时却不知道一个应用程序。
    *
    */
   int ROLE_SUPPORT = 1;

   /**
    * 角色提示,指示{@code  BeanDefinition}正在提供完全后台的角色,与最终用户无关。
    * 当注册完全属于{@link  org.springframework.beans.factory.parsing.ComponentDefinition}内部工作的bean时,将使用此提示。
    *
    */
   int ROLE_INFRASTRUCTURE = 2;

   // Modifiable attributes
   /**
    * 设置此bean定义的父定义的名称(如果有)。
    *
    */
   void setParentName(@Nullable String parentName);

   /**
    * 返回此bean定义的父定义的名称(如果有)。
    */
   @Nullable
   String getParentName();

   /**
    * 指定此Bean定义的Bean类名称。
    *  <p>可以在bean工厂后处理期间修改类名,通常用解析后的变体替换原始的类名。
    *
    * @see  #setParentName
    * @see  #setFactoryBeanName
    * @see  #setFactoryMethodName
    */
   void setBeanClassName(@Nullable String beanClassName);

   /**
    * 返回此Bean定义的当前Bean类名称。
    *  <p>请注意,在子定义从其父级继承/继承该子类名称的情况下,不必一定是在运行时使用的实际类名。
    * 同样,这可能只是调用工厂方法的类,或者在调用工厂方法的工厂bean引用的情况下它甚至可能为空。
    * 因此,<i>不要</ i>在运行时将其视为确定的bean类型,而仅将其用于单个bean定义级别的解析目的。
    *
    * @see  #getParentName()
    * @see  #getFactoryBeanName()
    * @see  #getFactoryMethodName()
    */
   @Nullable
   String getBeanClassName();

   /**
    * 覆盖此bean的目标作用域,并指定一个新的作用域名称。
    *
    * @see  #SCOPE_SINGLETON
    * @see  #SCOPE_PROTOTYPE
    */
   void setScope(@Nullable String scope);

   /**
    * 返回此Bean的当前目标作用域的名称,如果未知,则返回{@code  null}。
    *
    */
   @Nullable
   String getScope();

   /**
    * 设置是否应延迟初始化此bean。
    *  <p>如果{@code  false},则将在执行启动单例初始化的bean工厂启动时实例化bean。
    *
    */
   void setLazyInit(boolean lazyInit);

   /**
    * 返回此bean是否应延迟初始化,即不要在启动时急于实例化。
    * 仅适用于单例bean。
    *
    */
   boolean isLazyInit();

   /**
    * 设置该bean依赖于初始化的bean的名称。
    *  Bean工厂将确保首先初始化这些Bean。
    */
   void setDependsOn(@Nullable String... dependsOn);

   /**
    * 返回此bean依赖的bean名称。
    */
   @Nullable
   String[] getDependsOn();

   /**
    * 设置此bean是否适合自动连接到其他bean。
    *  <p>请注意,此标志旨在仅影响type-based(基于类型的)的自动装配(autowiring)。
    * 它不会影响按name的显式引用,如果指定的bean未标记为autowire候选也可以被解析。
    * 因此,如果名称匹配,按名称自动装配仍将注入Bean。
    */
   void setAutowireCandidate(boolean autowireCandidate);

   /**
    * 返回此bean是否适合自动连接到其他bean。
    */
   boolean isAutowireCandidate();

   /**
    * 设置此bean是否为自动装配的主要候选对象。
    *  <p>如果对于多个匹配候选对象中的一个bean,此值为{@code  true},则它将作为平局。
    */
   void setPrimary(boolean primary);

   /**
    * 返回此Bean是否为自动装配的主要候选对象。
    */
   boolean isPrimary();

   /**
    * 指定要使用的 factory bean(如果有)。
    * 这是用于调用指定工厂方法的bean的名称。
    *
    * @see  #setFactoryMethodName
    */
   void setFactoryBeanName(@Nullable String factoryBeanName);

   /**
    * 返回工厂bean名称(如果有)。
    */
   @Nullable
   String getFactoryBeanName();

   /**
    * 指定工厂方法(如果有)。
    * 将使用构造函数参数调用此方法,如果未指定任何参数,则不使用任何参数。
    * 该方法将在指定的factory bean(如果有)上被调用,否则将作为本地bean类上的静态方法被调用。
    *
    * @see  #setFactoryBeanName
    * @see  #setBeanClassName
    */
   void setFactoryMethodName(@Nullable String factoryMethodName);

   /**
    * 返回工厂方法名(如果有)。
    */
   @Nullable
   String getFactoryMethodName();

   /**
    * 返回此bean的构造函数参数值。
    *  <p>可以在bean工厂后处理期间修改返回的实例。
    *
    * @return  ConstructorArgumentValues对象(从不{@code  null})
    */
   ConstructorArgumentValues getConstructorArgumentValues();

   /**
    * 返回是否有为此bean定义的构造函数参数值。
    *  @since 5.0.2
    */
   default boolean hasConstructorArgumentValues() {
      return !getConstructorArgumentValues().isEmpty();
   }

   /**
    * 返回要应用到Bean的新实例的属性值。
    *  <p>可以在bean factory post-processing修改返回的实例。
    *
    * @return  MutablePropertyValues对象(从不{<@@code> null})
    */
   MutablePropertyValues getPropertyValues();

   /**
    * 返回是否有为此bean定义的属性值。
    *  @从5.0.2开始
    */
   default boolean hasPropertyValues() {
      return !getPropertyValues().isEmpty();
   }

   /**
    * 设置初始化方法的名称。
    *  @5.1起
    */
   void setInitMethodName(@Nullable String initMethodName);

   /**
    * 返回初始化方法的名称。
    *  @5.1起
    */
   @Nullable
   String getInitMethodName();

   /**
    * 设置destroy方法的名称。
    *  @5.1起
    */
   void setDestroyMethodName(@Nullable String destroyMethodName);

   /**
    * 返回destroy方法的名称。
    *  @5.1起
    */
   @Nullable
   String getDestroyMethodName();

   /**
    * 设置此{@code  BeanDefinition}的角色提示。
    * 角色提示为框架和工具提供了特定{@code  BeanDefinition}的角色和重要性的指示。
    *  @since 5.1
    * @see  #ROLE_APPLICATION
    * @see  #ROLE_SUPPORT
    * @see  #ROLE_INFRASTRUCTURE
    */
   void setRole(int role);

   /**
    * 获取此{@code  BeanDefinition}的角色提示。
    * 角色提示为框架和工具提供了特定{@code  BeanDefinition}的角色和重要性的指示。
    *
    * @see  #ROLE_APPLICATION
    * @see  #ROLE_SUPPORT
    * @see  #ROLE_INFRASTRUCTURE
    */
   int getRole();

   /**
    * 设置此bean定义的可读描述。
    *  @5.1起
    */
   void setDescription(@Nullable String description);

   /**
    * 返回此bean定义的可读描述。
    *
    */
   @Nullable
   String getDescription();

   // Read-only attributes

   /**
    * 根据Bean类或其他特定的元数据,返回此Bean定义的可解析类型。
    *  <p>通常可以在运行时合并的bean定义中完全解决此问题,而不必在配置时定义实例上完全解决。
    *
    * @return 可解析类型(可能为{@link  ResolvableType#NONE})@自5.2起
    * @see  ConfigurableBeanFactory#getMergedBeanDefinition
    */
   ResolvableType getResolvableType();

   /**
    * 返回此<b> Singleton </ b>是否具有在所有调用中返回的单个共享实例。
    *
    * @see  #SCOPE_SINGLETON
    */
   boolean isSingleton();

   /**
    * 返回此是否为<b> Prototype </ b>,并为每个调用返回一个独立的实例。
    *  @since 3.0
    * @see  #SCOPE_PROTOTYPE
    */
   boolean isPrototype();

   /**
    * 返回此bean是否为"抽象",即不打算实例化。
    */
   boolean isAbstract();

   /**
    * 返回此bean定义来自的资源的描述(以在发生错误的情况下显示上下文)。
    */
   @Nullable
   String getResourceDescription();

   /**
    * 返回原始的BeanDefinition,如果没有,则返回{@code  null}。
    * 允许检索修饰的bean定义(如果有)。
    *  <p>请注意,此方法返回直接发起者。
    * 遍历发起者链以找到用户定义的原始BeanDefinition。
    *
    */
   @Nullable
   BeanDefinition getOriginatingBeanDefinition();

}

总结

BeanDefinition通过继承继承了AttributeAccessor描述了一个bean的配置信息,通过继承了BeanMetadataElement包含Bean的数据源(即Bean的Class对象)。

但是BeanDefinition不包含bean的名字。通过

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

definitionHolder将持有beanName

Spring组件BeanDefinition 源码解析的更多相关文章

  1. Feign 系列(05)Spring Cloud OpenFeign 源码解析

    Feign 系列(05)Spring Cloud OpenFeign 源码解析 [TOC] Spring Cloud 系列目录(https://www.cnblogs.com/binarylei/p/ ...

  2. spring boot @Value源码解析

    Spring boot 的@Value只能用于bean中,在bean的实例化时,会给@Value的属性赋值:如下面的例子: @SpringBootApplication @Slf4j public c ...

  3. Spring Security 解析(七) —— Spring Security Oauth2 源码解析

    Spring Security 解析(七) -- Spring Security Oauth2 源码解析   在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因 ...

  4. 异步任务spring @Async注解源码解析

    1.引子 开启异步任务使用方法: 1).方法上加@Async注解 2).启动类或者配置类上@EnableAsync 2.源码解析 虽然spring5已经出来了,但是我们还是使用的spring4,本文就 ...

  5. Spring @Import注解源码解析

    简介 Spring 3.0之前,创建Bean可以通过xml配置文件与扫描特定包下面的类来将类注入到Spring IOC容器内.而在Spring 3.0之后提供了JavaConfig的方式,也就是将IO ...

  6. Spring Security 访问控制 源码解析

    上篇 Spring Security 登录校验 源码解析  分析了使用Spring Security时用户登录时验证并返回token过程,本篇分析下用户带token访问时,如何验证用户登录状态及权限问 ...

  7. .Net Core缓存组件(Redis)源码解析

    上一篇文章已经介绍了MemoryCache,MemoryCache存储的数据类型是Object,也说了Redis支持五中数据类型的存储,但是微软的Redis缓存组件只实现了Hash类型的存储.在分析源 ...

  8. .Net Core缓存组件(MemoryCache)源码解析

    一.介绍 由于CPU从内存中读取数据的速度比从磁盘读取快几个数量级,并且存在内存中,减小了数据库访问的压力,所以缓存几乎每个项目都会用到.一般常用的有MemoryCache.Redis.MemoryC ...

  9. Django 之 admin组件使用&源码解析

    admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.可以在项目的 settings.py 中的 INSTALLED ...

随机推荐

  1. C primer plus 6 编程练习答案

    环境:vs2017 /**编程练习2**/ */ #include<stdio.h> int main(void) { printf("张三\n"); printf(& ...

  2. 教你快速使用数据可视化BI软件创建4S店销售数据大屏

    灯果数据可视化BI软件是新一代人工智能数据可视化大屏软件,内置丰富的大屏模板,可视化编辑操作,无需任何经验就可以创建属于你自己的大屏.大家可以在他们的官网下载软件.   本文以4S店销售数据大屏为例为 ...

  3. 新手必看:PyCharm安装教程,Python开发者的有力工具

    PyCharm是由JetBrains打造的一款Python IDE,VS2010的重构插件Resharper就是出自JetBrains之手. 同时支持Google App Engine,PyCharm ...

  4. java开发学生宿舍管理系统源码

    开发环境: Windows操作系统开发工具: Eclipse+Jdk+Tomcat+MySQL 运行效果图

  5. iOS 中事件的响应链和传递链

    iOS事件链有两条:事件的响应链:Hit-Testing事件的传递链 响应链:由离用户最近的view向系统传递.initial view –> super view –> ….. –> ...

  6. SQL Server解惑——对象命名的唯一性小结

    关于SQL Server数据库中的对象命名的唯一性问题.例如表.索引.约束等数据库对象,有时候DBA在做数据库维护时,经常要创建对象或重命名对象,此时就会遇到一个问题,对象命名的唯一性问题.虽然是一个 ...

  7. php ./configure的一些参数及意义

    PHP编译参数的含义 ./configure –prefix=/usr/local/php php安装目录 –with-apxs2=/usr/local/apache/bin/apxs –with-c ...

  8. external IP 和 local IP 的区别

    外部(external)和本地(local) IP地址都具有相同的用途,不同之处在于范围.整个Internet使用外部或公共IP地址来定位计算机系统和设备.专用网络内部使用本地或内部IP地址来定位与其 ...

  9. 使用Sqlserver 2012 导出表数据为SQL脚本

    目录 前言 具体步骤 前言 很多时候,我们需要把数控库中的表的数据导出成SQL脚本的情形.然后,在别的库执行的情况. 以下,总结使用Sqlserver 2012数据库中表数据导出成SQL脚本的步骤. ...

  10. SQL Server无法连接到服务器 标题: 连接到服务器 ------------------------------ 无法连接到 DESKTOP-J6I1UIC\SQLEXPRESS1。 ------------------------------ 其他信息: 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。

    解决方案: 打开 SQL server 配置管理器 选择 SQL server 服务,找到服务器,右键启动