美文网首页
2-BeanDefinition

2-BeanDefinition

作者: 鹏程1995 | 来源:发表于2020-02-14 17:37 被阅读0次

    背景简介

    本文主要对 BeanDefinition接口进行简单的介绍。

    出现的原因

    在 Spring 工作时,明显的分成两个阶段:

    1. 从配置中读取信息,并生成此项目对应的 Bean 的定义,缓存在内存中。
    2. 用户【可能是人也可能是应用程序、应用框架】根据需要指示 Spring 生成指定的 bean 实例。

    所以需要一个至关重要的数据结构,来缓存从配置中读取的 Bean 的定义。

    职责

    缓存创建 Bean 所需的一切信息。

    BeanDefinition主要指责如下:

    1. 对 Bean 的创建的所有可能用到的字段进行了存取方法的定义
    2. 对 Bean 的创建中可能用到的一些常量进行了定义

    注意:既然是对从配置中读取的信息的处理结果,考虑到很多依赖于 Spring 的框架的扩展问题。 BeanDefinition还对生成自己的配置做了一个保存,方便用户进行自行定制。【此处有一些想法,参见"想法——程序员的思维"

    源码

    继承关系

    根据上面的职责大概能猜到,BeanDefinition中就是一些getter/setter方法、一些常量定义。其中的getter/setter方法中包括了创建 Bean 实例所有可能用到的字段。所以它继承了两个接口:

    1. AttributeAccessor:定义了通用的getter/setter,有点像 Map操作规范那种
    2. BeanMetadataElement: 定义了一个方法,用来获得生成此BeanDefinition的数据源
    1.png

    定义的常量

    /**
     * 单例 Bean 的生命周期常量
     *
     * 注意,具体的实现类可能会扩展其他的生命周期常量。
     *
     * @see #setScope
     */
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
    
    /**
     * 原型 Bean 的生命周期常量
     *
     * 注意,具体的实现类可能会扩展其他的生命周期常量。
     *
     * @see #setScope
     */
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
    
    
    /**
     * Role hint indicating that a {@code BeanDefinition} is a major part
     * of the application. Typically corresponds to a user-defined bean.
     */
    // 角色提示。表明这个 BD 是应用中的关键角色。这个角色通常对应用户定义的 Bean
    int ROLE_APPLICATION = 0;
    
    /**
     * Role hint indicating that a {@code BeanDefinition} is a supporting
     * part of some larger configuration, typically an outer
     * {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
     * {@code SUPPORT} beans are considered important enough to be aware
     * of when looking more closely at a particular
     * {@link org.springframework.beans.factory.parsing.ComponentDefinition},
     * but not when looking at the overall configuration of an application.
     */
    // 角色提示,表明 BD 是一些大型配置的支撑角色。通常是一些外部框架的支撑 bean 。在梳理整体应用
    // 配置时一般不关心它,但是在仔细查看特定框架实现时应该注意研读
    int ROLE_SUPPORT = 1;
    
    /**
     * Role hint indicating that a {@code BeanDefinition} is providing an
     * entirely background role and has no relevance to the end-user. This hint is
     * used when registering beans that are completely part of the internal workings
     * of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
     */
    // 角色提示,表示 BD 完全是一个后台服务,不会和使用者直接接触。在注册完全在 ComponentDefinition 内部工作
    // 的 BD 时会用这个
    int ROLE_INFRASTRUCTURE = 2;
    

    主要围绕 Bean 的生命周期和角色定义了一些常见的常量。

    问题

    为什么没有用 final修饰,会不会被篡改?见最后的扩展。

    定义的变量getter/setter

    因为直接粘贴源码太长了,我们直接去掉get/set取后面的名字来大概介绍都定义了哪些属性。

    • ParentName: 返回此 BeanDefinition的父BD的名称【id 或者 别名】
    • BeanClassName: Bean 实例对应的类名【为什么不直接返回 Class类型呢?参见"想法——职责单一问题”】
    • Scope:类的生命周期
    • LazyInit:Bean 的初始化是否进行懒加载
    • DependsOn:设置此 Bean 明确配置的依赖的 Bean。【后面会了解到,如果你在 Bean 中使用了对其他 Bean 的依赖注入,这个也算依赖,后面会维护在 Factory中。但是允许你主动配置或者新增对一些 Bean 的依赖】
    • AutowireCandidate: 判断其他 Bean 是否允许依赖注入此 Bean
    • Primary: 其他 Bean 做依赖注入有多个候选人时,是否优先选此 Bean
    • FactoryBeanName:在使用工厂方法构造此 BD 的实例时,使用哪个工厂
    • FactoryMethodName:在使用工厂方法构造此 BD 的实例时,使用工厂的哪个方法
    • ConstructorArgumentValues: 使用构造函数创建此 BD 的实例时,配置了哪些入参
    • PropertyValues:创建实例后使用getter/setter方法填充实例属性时,要配置哪些入参
    • Role: BD 对应的实例的角色
    • ResourceDescription: 获得创建这个 BD 的源的描述信息
    • Source: 获得创建这个 BD 的源
    • OriginatingBeanDefinition:未知。。。。。。。。。

    还有基于以上属性的一些判断函数,例如是不是单例、是不是原型之类的,不再赘述。

    一些想法

    程序员的思维

    关于在写代码,搭建框架甚至是日常工作中的一些操作的思路:

    1. 尽可能的使用封装之后的东西,这样有问题你能找到负责的人,使用顺畅。而且封装之后往往意味着使用更加简单。【API接口】
    2. 在工作时对 API 问题进行沟通时尽可能绕过行话直接说原理,这样调用者能更好的把控整个流程,有时还能帮你找出一些问题。
    3. 在提供 SPI 时,和 API 不同的是,如果可行的话,提供一个接口,让调用者能够拿到最原始的数据,这样会使框架在某些情况下更方便用户进行定制。当然,要对自己的解析流程定好规范和校验,防止由于用户的不规范操作造成大范围的问题。

    职责单一问题

    在定义数据结构时,要明确你要的是什么?

    BD的职责只是一个用于存储的数据结构而已,在存储 Bean 对应的类时采用String足以存储,该类名是从配置文件中读取的。不一定是对的,可能该类不存在,也可能未加载,如果在这里就传入Class,那么在最开始的注册阶段就会引起大量的冗余引入、校验操作。

    扩展

    interface中的常量定义没有用修饰词

    • interface中的常量定义不用修饰,都是public static final
    • interface中定义的方法不用修饰,都是public

    丢人!!!!

    相关文章

      网友评论

          本文标题:2-BeanDefinition

          本文链接:https://www.haomeiwen.com/subject/mcdjfhtx.html