Spring源码学习之BeanDefinition源码解析

2023-11-18

本文作者:磊叔_GLMapper本文链接:https://juejin.cn/post/6844903553820000269

    Bean的定义主要由BeanDefinition来描述的。作为Spring中用于包装Bean的数据结构,今天就来看看它的面纱下的真容吧。

首先就是BeanDefinition的类定义:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement

我们都知道在JAVA中,接口是不能用来new出新的对象的,那么在Spring中,到底将XML解析出来的Bean包装成了什么呢?可以看看下面BeanDefinition继承类的属性

来看看BeanDefinition一个继承结构吧(均是与BeanDefinition有直接关联的类或者接口)!

从类图中可以看出,BeanDefinition继承了AttributeAccessor和BeanMetadataElement两个接口;一个一个看。

AttributeAccessor

AttributeAccessor接口定义了最基本的对任意对象的元数据的修改或者获取,主要方法有:

//将name定义的属性设置为提供的value值。如果value的值为null,则该属性为{@link #removeAttribute removed}。
//通常,用户应该注意通过使用完全限定的名称(可能使用类或包名称作为前缀)来防止与其他元数据属性重叠。
void setAttribute(String name, Object value);
//获取标识为name的属性的值。
Object getAttribute(String name);
//删除标识为name的属性,并返回属性值
Object removeAttribute(String name);
//如果名为name的属性是否存在,存在返回true,否则返回false。
boolean hasAttribute(String name);
//返回所有属性的名称。
String[] attributeNames();

BeanMetadataElement

BeanMetadataElement接口提供了一个getResource()方法,用来传输一个可配置的源对象。

//返回此元数据元素的配置源对象(可能为null)。
Object getSource();

BeanDifinition源码分析

一个BeanDefinition描述了一个bean的实例,包括属性值,构造方法参数值和继承自它的类的更多信息。BeanDefinition仅仅是一个最简单的接口,主要功能是允许BeanFactoryPostProcessor 例如PropertyPlaceHolderConfigure 能够检索并修改属性值和别的bean的元数据(译注)。

//标准单例作用域的作用域标识符:“singleton”。
//对于扩展的bean工厂可能支持更多的作用域。
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
//标准原型作用域的范围标识符:“prototype”。
//对于扩展的bean工厂可能支持更多的作用域。
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
//表示BeanDefinition是应用程序主要部分的角色提示。通常对应于用户定义的bean。
int ROLE_APPLICATION = 0;

ROLE_SUPPORT =1实际上就是说,我这个Bean是用户的,是从配置文件中过来的。

//表示BeanDefinition是某些大型配置的支持部分的角色提示,通常是一个外部ComponentDefinition。
//当查看某个特定的ComponentDefinition时,认为bean非常重要,
//以便在查看应用程序的整体配置时能够意识到这一点。
int ROLE_SUPPORT = 1;

ROLE_INFRASTRUCTURE = 2就是我这Bean是Spring自己的,和你用户没有一毛钱关系。

//角色提示表明一个BeanDefinition是提供一个完全背景的角色,并且与最终用户没有关系。
//这个提示用于注册完全是ComponentDefinition内部工作的一部分的bean
int ROLE_INFRASTRUCTURE = 2;

上面是BeanDifinition的一些基本属性信息,一个就是标识下当前Bean的作用域,另外就是标识一下这个Bean是内部的还是外部的。下面来看这个接口为其子类都提供了哪些具体的行为方法:

1.当前Bean父类名称get&set方法

//如果父类存在,设置这个bean定义的父定义的名称。
void setParentName(String parentName);
//如果父类存在,则返回当前Bean的父类的名称
String getParentName();

2.当前Bean的className get&set方法

//指定此bean定义的bean类名称。
//类名称可以在bean factory后期处理中修改,通常用它的解析变体替换原来的类名称。
void setBeanClassName(String beanClassName);

//返回此bean定义的当前bean类名称。
//需要注意的是,这不一定是在运行时使用的实际类名,以防子类定义覆盖/继承其父类的类名。
//此外,这可能只是调用工厂方法的类,或者它 在调用方法的工厂bean引用的情况下甚至可能是空的。
//因此,不要认为这是在运行时定义的bean类型,而只是将其用于在单独的bean定义级别进行解析。
String getBeanClassName();

3.Bean的作用域get&set方法

//覆盖此bean的目标范围,指定一个新的范围名称。
void setScope(String scope);
//返回此bean的当前目标作用域的名称,如果没有确定,返回null
String getScope();

4.懒加载的get&set方法

//设置这个bean是否应该被延迟初始化。如果{false},那么这个bean将在启动时由bean工厂实例化,
//这些工厂执行单例的立即初始化。
//懒加载 <bean lazy-init="true/false">
void setLazyInit(boolean lazyInit);
//返回这个bean是否应该被延迟初始化,即不是在启动时立即实例化。只适用于单例bean。
boolean isLazyInit();

5.依赖关系设置

//设置这个bean依赖被初始化的bean的名字。bean工厂将保证这些bean首先被初始化。
//<bean depends-on="">
void setDependsOn(String... dependsOn);
//返回这个bean依赖的bean名称。
String[] getDependsOn();

6.是否是自动转配设置

//设置这个bean是否是获得自动装配到其他bean的候选人。
//需要注意是,此标志旨在仅影响基于类型的自动装配。
//它不会影响按名称的显式引用,即使指定的bean没有标记为autowire候选,也可以解决这个问题。
//因此,如果名称匹配,通过名称的自动装配将注入一个bean。
void setAutowireCandidate(boolean autowireCandidate);

//返回这个bean是否是自动装配到其他bean的候选者。就是是否在其他类中使用autowired来注入当前Bean的
//是否为被自动装配 <bean autowire-candidate="true/false">
boolean isAutowireCandidate();

7.主候选Bean

//是否为主候选bean    使用注解:@Primary
void setPrimary(boolean primary);
//返回这个bean是否是主要的autowire候选者。
boolean isPrimary();

8.定义创建该Bean对象的工厂类

//指定要使用的工厂bean(如果有的话)。这是调用指定的工厂方法的bean的名称。
void setFactoryBeanName(String factoryBeanName);
//返回工厂bean的名字,如果有的话。
String getFactoryBeanName();

9.创建该Bean对象的工厂方法

//如果有的话,指定工厂方法。
//这个方法先将通过构造函数参数被调用,或者如果参数,将调用该方法的无参数构造。
//方法将在指定的工厂bean(如果有的话)上被调用,或者作为本地bean类的静态方法被调用。
void setFactoryMethodName(String factoryMethodName);
//如果存在,返回工厂方法名
String getFactoryMethodName();

10.返回此bean的构造函数参数值。

//返回此bean的构造函数参数值。
ConstructorArgumentValues getConstructorArgumentValues();

11.获取普通属性集合

//获取普通属性集合
MutablePropertyValues getPropertyValues();

12.当前Bean的基本特性

//是否是单例的
boolean isSingleton();
//是否是多例的
boolean isPrototype();
//是否是抽象类
boolean isAbstract();

13.当前Bean的应用

//获取这个bean的应用
int getRole();

13.可读描述

//返回对bean定义的可读描述。
String getDescription();
//返回该bean定义来自的资源的描述
String getResourceDescription();

//返回原始的BeanDefinition;如果没有,则返回null。允许检索装饰的bean定义(如果有的话)。
//注意,这个方法返回直接的发起者。迭代原始链,找到用户定义的原始BeanDefinition。
BeanDefinition getOriginatingBeanDefinition();

从上面的属性和方法分析可以看出,BeanDefinition对于一个Bean的描述做了较为完整的一套约束。这为后续的子类提供的最基本的职责和属性。


更多精彩,更多技术请关注:码蚁在线(coding_online)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring源码学习之BeanDefinition源码解析 的相关文章

随机推荐

  • json-server -g报错

    在vscode终端报 在系统上禁止运行脚本 的话 在下面输入set ExecutionPolicy RemoteSigned 前提是你是以管理员模式运行vscode 然后重新输入 json server v即可
  • 低代码?未来会代替如今的代码吗?

    一 前言 如果选择用一个关键词来代表即将过去的2020年 我相信所有人都会认同是 新冠 疫情来得太快就像龙卷风 短短数月就阻断了全世界范围内无数人与人之间的物理连接 但好在 我们已经全面迈入互联网时代 N95口罩再厚 也阻挡不了信息比特流的
  • Translation Lookaside Buffer (TLB)

    CPU每次访问虚拟内存 虚拟地址都必须转换为对应的物理地址 从概念上说 这个转换需要遍历页表 页表是三级页表 就需要3次内存访问 就是说 每次虚拟内存访问都会导致4次物理内存访问 简单点说 如果一次虚拟内存访问对应了4次物理内存访问 肯定比
  • 如何访问WEB-INF文件夹下的jsp文件

    我们都知道不能直接访问WEB INF文件夹下的jsp文件 那应该怎样访问呢 首先 WEB INF目录是Java WEB应用的安全目录 客户端无法访问 只有服务端可以访问 然后 为什么要这么设计 这样做的初衷是在WEB INF文件夹下放一些不
  • VScode使用PlatformIO IDE时PIO Home一直loading的问题

    近来刚接触 Arduino 想做个小项目 网上都都说 Arduino 自带的IDE不人性化 推荐的是用 VScode搭配 PlatformIO 但是这个插件非常不稳定 各种坑 有的时候安装 Library 点击了 Add 以后会一直转 等半
  • 汇编实验(循环程序设计)(排序以及找非负数)

    这里的排序 用的是冒泡排序 首先 先是说一下找非负数的想法 负数 TEST 80H 之后不为0 我们可以用这个性质来做 1 FIND POSITIVE NUMBER LEA SI FIRST LEA DI SECOND MOV CX N L
  • pg数据库日志 linux,PostgreSQL删除pg_xlog日志

    PostgreSQL的pg xlog下有大量日志 空间不足 如何删除 Darren1 postgres usr local pgsql data pg xlog gt ls 000000010000000000000008 00000028
  • Python调试工具pdb使用详解

    Python调试工具pdb使用详解 1 前言 2 参考文档 3 pdb简介 4 pdb使用命令行调试 4 1 举例代码 4 2 调试器命令 4 2 1 进入pdb调试模式 4 2 2 帮助指令 4 2 3 控制程序执行 4 2 4 设置断点
  • python数据驱动库_Python3

    1 DDT简介 Data Driven Tests DDT 即数据驱动测试 它允许您通过不同的测试数据来运行同一个测试用例 使它作为多个测试用例出现 其官方文档给出的定义如下 DDT Data Driven Tests allows you
  • 利用MATLAB&C语言生成&读取.dat文件

    利用MATLAB C语言生成 读取 dat文件 MATLAB生成 dat文件 MATLAB读取 dat文件 方式一 方式二 C语言生成 dat文件 C语言读取 dat文件 注意事项 有时候 需要在matlab或c语言编程环境中写入或读取 d
  • Linux Socket 事件触发模型 epoll 示例 这里会写一个用C语言的TCP服务器的完全实现的简单程序

    背景介绍 通常的网络服务器实现 是对每一个连接使用一个单独的线程或进程 对高性能应用而言 由于需要同时处理非常多的客户请求 所以这种方式并不能工作得很好 因为诸如资源使用和上下文切换所需的时间影响了在一时间内对多个客户端进行处理 另一个可选
  • window怎么下载和使用nginx

    希望下面的东西对你有帮助 我们一起学习 一起加油 1 首先去官网下载 http nginx org en download html 2 下载后解压到指定文件夹 如图 3 启动negix有如下种 1 双击nginx应用程序即可 闪烁两下 即
  • FIddler之Fiddler移动端抓包

    前言 笔者今天的这篇文章呢 想使用通俗易懂的话语 让大家明白以下内容 什么是抓包哪些场景需要用到抓包Fiddler抓包的原理怎样使用Fiddler进行移动端抓包 一 抓包 包 Packet 是TCP IP协议通信传输中的数据单位 一般也称
  • leetcode-动态规划【背包问题】

    背包问题篇 基础背包 416 分割等和子集 1049 最后一块石头的重量ii 494 目标和 474 一和零 完全背包 518 零钱兑换ii 377 组合总和iv 70 爬楼梯 322 零钱兑换 279 完全平方数 139 单词拆分 多重背
  • 树06--二叉树中和为某一值的路径

    树06 二叉树中和为某一值的路径 jz24 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 输入一颗二叉树的根节点和一个整数 按字典序打印出二叉树中结点值的和为输入整数的所有路径 路径定义为从树的根结点开始往下一直到叶结点所经
  • 课程设计步骤模板计算机,计算机络基础校园课程设计模板.doc

    计算机络基础校园课程设计模板 哈尔滨理工大学 计算机网络基础课程设计 学生姓名 姜金辉 学 号 1130370210 学 院 荣成学院 系 别 软件工程系 专业班级 计应11 2 设计 论文 题目 计算机网络课程设计 指导教师 徐辉 201
  • Vue后台 - 利用 mockjs 完成数据的获取、编辑、增加、删除和分页

    一 前言 很多vue后台的模板都用了mockjs来模拟假数据 并且利用mockjs的拦截请求完成了很多功能 比如数据的获取 编辑 增加 删除等 所以就利用了一个后台模板 在这基础上删除了一些页面 根据一个项目原型自己试着学习mockjs的一
  • 潜入地图_潜入

    潜入地图 By Taylor Barkley Program Officer for Tech and Innovation at Stand Together 提供者 Stand Together技术与创新计划官Taylor Barkle
  • Git, Gitlab使用文档

    一 前期准备 配置网络 连接局域网 下载 windows git 注册gitlab账号 注册后需要管理员确认通过 二 配置ssh 本处来源 docker下gitlab安装配置使用 1 打开本地git bash 使用如下命令生成ssh公钥和私
  • Spring源码学习之BeanDefinition源码解析

    本文作者 磊叔 GLMapper本文链接 https juejin cn post 6844903553820000269 Bean的定义主要由BeanDefinition来描述的 作为Spring中用于包装Bean的数据结构 今天就来看看