Spring 源码分析(二)——GenericBeanDefinition 分析

BeanDefinition 中存储着 Bean 的定义信息,它具有属性值、构造函数参数值以及具体实现 Bean 提供的进一步信息,在学习 SpringBean 初始化流程之前,还是非常有必要先了解一下 BeanDefinition

一、注册 Bean 示例

首先,本文先举一个使用 BeanDefinition 创建 Bean 的小例子:

import com.nineya.spring.entity.Post;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;

import java.util.ArrayList;
import java.util.List;

public class SpringMain {
    public static void main(String[] args) {
        // 创建bean工厂
        DefaultListableBeanFactory context = new DefaultListableBeanFactory();

        //构造bean定义
        GenericBeanDefinition gbd = new GenericBeanDefinition();
        gbd.setBeanClass(Post.class);

        // 设置属性
        List<PropertyValue> propertyValues = new ArrayList<>();
        propertyValues.add(new PropertyValue("id", 123L));
        propertyValues.add(new PropertyValue("title", "title"));
        gbd.setPropertyValues(new MutablePropertyValues(propertyValues));

        //注册到环境上下文
        context.registerBeanDefinition("post", gbd);

        // 通过class取得bean
        Post post = context.getBean(Post.class);
        System.out.println(post + " : " + post.hashCode());

        // 通过名称取得bean
        post = (Post) context.getBean("post");
        System.out.println(post + " : " + post.hashCode());
    }
}

执行结果输出:

Post(id=123, title=title, categories=null, tags=null, content=null) : 1339167804
Post(id=123, title=title, categories=null, tags=null, content=null) : 1339167804

二、GenericBeanDefinition 结构

GenericBeanDefinition 类继承关系图如下:

GenericBeanDefinition 类继承关系图

逐个对 GenericBeanDefinition 继承的类/接口进行分析:

BeanMetadataElement 接口: BeanMetadataElement 提供了获取数据源的方式,也就是可以指导 Bean 是来自哪个类,由携带配置源对象的 Bean 元数据元素实现的接口。

接口说明
Object getSource()返回此元数据元素的配置源

AttributeAccessorSupport 抽象类: 支持 AttributeAccessor 属性存取接口,内部使用的 LinkedHashMap,提供
所有方法的基本实现,由子类扩展。

接口说明
void setAttribute(String name, @Nullable Object value)设置属性
Object getAttribute(String name)取得属性
Object removeAttribute(String name)删除并返回属性
boolean hasAttribute(String name)判断属性是否存在
String[] attributeNames()取得所有属性的名称

以上这两个接口的实现皆与 GenericBeanDefinition 无关联,这是公共的基础类。

BeanMetadataAttributeAccessor 类: 将元数据参数封装为 BeanMetadataAttribute,用于 Bean 的元数据和属性上下文操作的实现类。

接口说明
void setSource(@Nullable Object source)为这个元数据元素设置配置源
void addMetadataAttribute(BeanMetadataAttribute attribute)将给定的BeanMetadataAttribute添加到该访问器的属性集
BeanMetadataAttribute getMetadataAttribute(String name)在这个访问器的属性集中查找给定的BeanMetadataAttribute

BeanDefinition 接口

接口说明
void setParentName(@Nullable String parentName)设置此 bean 定义的父定义的名称(如果有的话)
String getParentName()返回此 bean 定义的父定义的名称(如果有的话)
void setBeanClassName(@Nullable String beanClassName)指定此 bean 定义的 bean 类名。类名可以在 bean 工厂后期处理期间修改,通常是用解析后的类名替换原来的类名
String getBeanClassName()返回此 bean 定义的当前bean类名称。注意,这并不一定是运行时使用的实际类名,例如子定义覆盖/继承其父类名。
void setScope(@Nullable String scope)重写此 bean 的目标范围,指定一个新的范围名
String getScope()返回此 bean 的当前目标作用域的名称
void setLazyInit(boolean lazyInit)设置该 bean 是否应该延迟初始化
boolean isLazyInit()返回该 bean 是否应该延迟初始化,即在启动时实例化
void setDependsOn(@Nullable String… dependsOn)设置此 bean 所依赖的初始化 bean 的名称, bean 工厂将保证这些 bean 首先被初始化
String[] getDependsOn()返回此 bean 所依赖的初始化 bean 的名称
void setAutowireCandidate(boolean autowireCandidate)设置该 bean 是否为自动连接到其他 bean 的候选 bean
boolean isAutowireCandidate()返回该 bean 是否是自动连接到其他 bean 的候选 bean
void setPrimary(boolean primary)设置此 bean 是否为主要自动装配候选
boolean isPrimary()返回此 bean 是否是自动装配的主要候选
void setFactoryBeanName(@Nullable String factoryBeanName)指定要使用的工厂 bean 名称
String getFactoryBeanName()返回工厂 bean 名称(如果有的话)
void setFactoryMethodName(@Nullable String factoryMethodName)指定一个工厂方法,该方法将使用构造函数参数调用,如果没有指定参数,则不使用参数调用。该方法将在指定的工厂 bean 上调用,或者作为本地 bean 类上的静态方法调用。
String getFactoryMethodName()返回一个工厂方法
ConstructorArgumentValues getConstructorArgumentValues()返回此 bean 的构造函数参数值
boolean hasConstructorArgumentValues()判断此 bean 是否定义了构造函数参数值
MutablePropertyValues getPropertyValues()返回应用于 bean 的新实例的属性值
boolean hasPropertyValues()判断此 bean 是否定义了属性值
void setInitMethodName(@Nullable String initMethodName)设置初始化器方法的名称
String getInitMethodName()返回初始化方法的名称
void setDestroyMethodName(@Nullable String destroyMethodName)设置销毁方法的名称
String getDestroyMethodName()返回销毁方法的名称
void setRole(int role)为这个 BeanDefinition 设置角色提示
int getRole()获取这个 BeanDefinition 的角色提示
void setDescription(@Nullable String description)设置此 bean 定义的人类可读的描述
String getDescription()取得此 bean 定义的人类可读的描述
ResolvableType getResolvableType()根据 bean 类或其他特定元数据,返回此 bean 定义的可解析类型
boolean isSingleton()判断此 bean 是否是单例
boolean isPrototype()判断此 bean 是否是原型
boolean isAbstract()返回此 bean 是否是“抽象的”,即不需要实例化
String getResourceDescription()返回此 bean 定义所来自的资源的描述(以便在出现错误时显示上下文)
BeanDefinition getOriginatingBeanDefinition()返回原始的 BeanDefinition

AbstractBeanDefinition 抽象类: AbstractBeanDefinition 是具体的、BeanDefinition 类的基类,分解出 GenericBeanDefinitionRootBeanDefinitionChildBeanDefinition 的公共属性和逻辑。

接口说明
void overrideFrom(BeanDefinition other)使用给定 BeanDefinition 定义重新当前 BeanDefinition 中的设置
void applyDefaults(BeanDefinitionDefaults defaults)将提供的默认值应用到此 bean
void setBeanClass(@Nullable Class<?> beanClass)为这个 bean 指定类
Class<?> getBeanClass() throws IllegalStateException返回 bean 定义的指定类
boolean hasBeanClass()返回该定义是否指定了 bean
Class<?> resolveBeanClass(@Nullable ClassLoader classLoader)确定被包装bean的类,如果需要,从指定的类名解析它
void setAbstract(boolean abstractFlag)默认为“false”。指定 true 告诉 bean 工厂在任何情况下都不要尝试实例化 bean
Boolean getLazyInit()返回该 bean 是否应该延迟初始化
void setAutowireMode(int autowireMode)设置自动装配模式。这决定是否会发生 bean 引用的自动检测和设置
int getAutowireMode()返回 bean 定义中指定的自动装配模式
int getResolvedAutowireMode()返回已解析的自动装配代码
void setDependencyCheck(int dependencyCheck)设置依赖项检查代码
int getDependencyCheck()返回依赖项检查代码
addQualifier(AutowireCandidateQualifier qualifier)注册一个用于自动装配候选解析的限定符,以限定符的类型名称为键值
boolean hasQualifier(String typeName)返回此 bean 是否具有指定的限定符
AutowireCandidateQualifier getQualifier(String typeName)返回映射到所提供类型名称的限定符
Set<AutowireCandidateQualifier> getQualifiers()返回所有已注册的限定符
void copyQualifiersFrom(AbstractBeanDefinition source)将所提供的 AbstractBeanDefinition 中的限定符复制到当前 BeanDefinition
public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier)指定用于创建 bean 实例的回调,作为声明式指定工厂方法的替代方法
Supplier<?> getInstanceSupplier()返回用于创建 bean 实例的回调(如果有的话)
void setNonPublicAccessAllowed(boolean nonPublicAccessAllowed)指定是否允许访问非公共构造函数和方法,如果外部化元数据指向它们
boolean isNonPublicAccessAllowed()返回是否允许访问非公共构造函数和方法
void setLenientConstructorResolution(boolean lenientConstructorResolution)指定是否在宽限模式下解析构造函数
boolean isLenientConstructorResolution()返回以宽松模式还是严格模式解析构造函数
void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues)为这个 bean 指定构造函数参数值
void setPropertyValues(MutablePropertyValues propertyValues)指定此 bean 的属性值(如果有的话)
void setMethodOverrides(MethodOverrides methodOverrides)bean 指定方法重写(如果有的话)
MethodOverrides getMethodOverrides()返回 IoC 容器要覆盖的方法的信息。如果没有方法重写,该参数将为空。
boolean hasMethodOverrides()是否为此 bean 定义了方法重写
void setEnforceInitMethod(boolean enforceInitMethod)指定配置的初始化方法是否为默认值
boolean isEnforceInitMethod()指示配置的初始化方法是否为默认值
void setEnforceDestroyMethod(boolean enforceDestroyMethod)设置配置的销毁方法是否为默认值
boolean isEnforceDestroyMethod()指定配置的销毁方法是否为默认值
void setSynthetic(boolean synthetic)设置这个 bean 定义是否是“合成的”
boolean isSynthetic()返回此 bean 定义是否是“合成的”,即不是由应用程序本身定义的
void setResource(@Nullable Resource resource)设置此 bean 定义所来自的资源(以便在出现错误时显示上下文)
setResourceDescription(@Nullable String resourceDescription)设置此 bean 定义所来自的资源的描述(以便在出现错误时显示上下文)
void setOriginatingBeanDefinition(BeanDefinition originatingBd)如果有的话,设置原始的(例如装饰过的) BeanDefinition
void validate() throws BeanDefinitionValidationException验证这个 BeanDefinition
void prepareMethodOverrides() throws BeanDefinitionValidationException验证并准备为此 bean 定义的方法重写。检查具有指定名称的方法是否存在
void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException验证并准备给定的方法重写。检查具有指定名称的方法是否存在,如果没有找到则将其标记为未重载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/10022.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud微服务技术栈之网关服务Gateway

文章目录SpringCloud微服务技术栈之网关服务Gateway前言网关服务Gateway的基本概念Gateway的体系结构Gateway的主要功能网关服务Gateway的架构设计架构设计方案示例代码网关服务Gateway的实践操作1. 创建工程2. 配置路由规则3. 实现过滤器4. 集成服务注册中心5. 启动网关服务器…

2020年11月信息系统项目管理师真题(综合+案例)

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 1、&#xff08; &#xff09;使系统的描述及信息模型的表示与客观实体相对应&#xff0c;符合人们的思维习惯&#xff0c;有利于系统开发过程中用户与开发人员的…

Redhat6.7离线安装rabbitmq

一、下载资源文件&#xff08;.rpm文件&#xff09; 链接: https://pan.baidu.com/s/1j2Ze_Jjm0oMrP-r95PPCtA?pwdv3is 提取码: v3is 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 创建rabbit文件夹Mkdir rabbit 三、通过ftp上传文件 四、安装erlang环境 …

强大到让人无法想象的ChatGPT-5即将发布,上千名人士却紧急叫停

目录 【ChatGPT 5简介】 【ChatGPT 5的潜在应用】 【ChatGPT 5的潜在危险】 ChatGPT4还没有好好体验&#xff0c;比GPT4强大1000倍的ChatGPT5又即将发布&#xff01;届时将彻底改变人工智能领域&#xff0c;并改变我们现有的世界 【ChatGPT 5简介】 OpenAI计划在2023年12月发…

面试了上百位性能测试后,我发现了一个令人不安的事实...

在企业中负责技术招聘的同学&#xff0c;肯定都有一个苦恼&#xff0c;那就是招一个合适的测试太难了&#xff01;若要问起招哪种类型的测试最难时&#xff0c;相信很多人都会说出“性能测试”这个答案。 每当发布一个性能测试岗位&#xff0c;不一会就能收到上百份简历&#…

kafka-4 生产者和消费者

kafka的生产者和消费者四、 生产者4.1 分区分配策略4.2 副本和消息消费4.2.1 副本&#xff08;AR、ISR、OSR&#xff09;4.2.2 HW与LEO4.2.3 ISR 集合和 HW、LEO的关系五、消费者5.1 分区分配策略5.2 消费者offset的存储四、 生产者 4.1 分区分配策略 &#xff08;1&#xff…

Webpack 实践:配置、性能优化和最佳实践

总结 通过以下的配置示例和性能优化策略&#xff0c;我们希望能帮助你在 Webpack 实践中获得更好的开发体验和项目性能。这里仅仅是冰山一角&#xff0c;Webpack 的功能还有很多等待你去探索。 在本篇文章中&#xff0c;我们将深入探讨 Webpack 的实践&#xff0c;包括配置示例…

Python 小型项目大全 71~75

七十一、声音模拟 原文&#xff1a;http://inventwithpython.com/bigbookpython/project71.html 类似于西蒙电子玩具&#xff0c;这款识记游戏使用第三方playsound模块&#xff0c;播放四种不同的声音&#xff0c;分别对应键盘上的A、S、D、F键。当你成功地重复游戏给你的图案时…

【SSL】ssl证书简介、ssl证书生成工具与ssl证书生成步骤

ssl证书简介、ssl证书生成工具与ssl证书生成步骤一、ssl证书是什么&#xff1f;二、ssl证书生成工具有哪些&#xff1f;2.1、工具一&#xff1a;CFSSL2.2、工具二&#xff1a;OpenSSL2.3、工具三&#xff1a;XCA三、ssl证书有什么用&#xff1f;四、ssl证书生成步骤4.1 步骤1&a…

6基于二阶锥规划的主动配电网最优潮流求解

matlab代码&#xff1a;基于二阶锥规划的主动配电网最优潮流求解 参考文献&#xff1a;主动配电网多源协同运行优化研究_乔珊 摘要&#xff1a;最优潮流研究在配 电网规划运行 中不可或缺 &#xff0c; 且在大量分布式能源接入 的主动配 电网环境下尤 为重要 。传统的启发式算…

【安全防御】防火墙(二)

目录 1、防火墙如何处理双通道协议 2、防火墙如何处理nat 3、防火墙支持哪些NAT&#xff0c;主要应用的场景是什么&#xff1f; 4、当内网PC通过公网域名解析访问内网服务器的时候&#xff0c;会存在什么问题&#xff0c;如何解决&#xff1f;请详细说明 5.防火墙使用VRRP…

2023-04-10 网络流和最大流问题

网络流和最大流问题 1 网络流和最大流问题阐述 网络流基本概念 网络流图中&#xff0c;从源点出发&#xff0c;在满足每条边容量限制的条件下&#xff0c;汇点t最多能接收多少流量 s:sourcet:target 网络流需要满足的限制 容量限制平衡限制&#xff1a;除了源点s和汇点t&a…

第三章 spring IOC与Bean环境搭建与应用

1、手动导入Lib包搭建环境 1.1、下载Apache Common Logging API https://commons.apache.org/proper/commons-logging/download_logging.cgi 1.2、下载spring https://repo.spring.io/ui/native/release/org/springframework/spring/5.3.13/ 名称作用docs包含 Spring 的 …

李宏毅2021春季机器学习课程视频笔记9-再谈宝可梦分类器

宝可梦与数码宝贝很类似。 明显数码宝贝的线条更加复杂&#xff0c;宝可梦更简单&#xff0c;可以从这个角度出发。 利用一些边缘检测工具&#xff08;&#xff43;&#xff41;&#xff4e;&#xff4e;&#xff59;&#xff09;&#xff0c;&#xff45;用来计算线条的复杂程…

CSDN,感谢遇见【我的一周年创作纪念日】

机缘 第一次遇见CSDN已经是7年前的事了&#xff0c;那时的我还是一名初二的学生&#xff0c;由于沉迷于玩具战争这款游戏&#xff08;很遗憾这款游戏已经停服&#xff09;&#xff0c;里面有许多大佬利用各种手段去开挂&#xff0c;所以我意外的接触到了浏览器抓包等计算机技术…

考研数二第十四讲 牛顿-莱布尼茨公式与用定义法求解定积分

牛顿-莱布尼茨公式 牛顿-莱布尼茨公式在微分与积分以及不定积分与定积分之间架起了一座桥梁&#xff0c;因此&#xff0c;这个公式又被称为微积分基本公式。 微积分基本公式的简单推导 在看微积分基本公式之前&#xff0c;我们先来看一个有点特殊的函数&#xff0c;积分上限…

HashMap和HashTable的区别

目录一、HashMap和HashTable的区别二、验证结论1.线程安全和不安全2.继承的父类不同3.对null key和null value的支持不同4.初始化和扩容方式不同一、HashMap和HashTable的区别 1.HashMap方法没有synchronize修饰&#xff0c;线程非安全&#xff0c;HashTable安全 拓展:HashTabl…

OctoClock CDA 2990

CDA 2990 CDA 2990为时钟和PPS分发设备&#xff0c;支持外部一路时钟和PPS输入&#xff0c;最高支持8路时钟和PPS输出。同时CDA 2990可选配带GPS模块版本&#xff0c;可外接GPS天线&#xff0c;支持通过GPS锁定时钟和PPS信号输出。CDA 2990主要用于多台USRP设备进行同步。 CDA…

康耐视Designer-通过康耐视VC5与Omron PLC CJ2MEthernet IP通讯详细设置步骤

测试使用软件版本 Designer Version: 2.7 EDS File Version: 1.01 CX Programmer Version: 9.2 Network Configurator Version: 3.56 测试使用硬件 Cognex Vision Controller VC5 CIC500&CIC2900 OMRON PLC: CJ2M CPU31 PLC端设置 1.在Network Configurator中安装…

算法 二叉树2 || 层序遍历 226.翻转二叉树 101. 对称二叉树 104.二叉树的最大深度 111 二叉树的最小深度 222.完全二叉树的节点个数

102 二叉树的层序遍历 队列先进先出&#xff0c;符合一层一层遍历的逻辑&#xff0c;而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。 而这种层序遍历方式就是图论中的广度优先遍历&#xff0c;只不过我们应用在二叉树上。 迭代法&#xff1a; /*** Definition for …