2-BeanDefinition

2020-02-14  本文已影响0人  鹏程1995

背景简介

本文主要对 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取后面的名字来大概介绍都定义了哪些属性。

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

一些想法

程序员的思维

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

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

职责单一问题

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

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

扩展

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

丢人!!!!

上一篇 下一篇

猜你喜欢

热点阅读