mini-Spring-BeanDefinition和BeanDefinitionRegistry(二)

在这里插入图片描述
Bean工厂
首先我们需要定义 BeanFactory 这样一个 Bean 工厂,提供 Bean 的获取方法 getBean(String name),之后这个 Bean 工厂接口由抽象类 AbstractBeanFactory 实现,可以统一模板。继承抽象类 AbstractBeanFactory 后的 AbstractAutowireCapableBeanFactory 就可以实现相应的抽象方法了。因为 AbstractAutowireCapableBeanFactory 本身也是一个抽象类,所以它只会实现属于自己的抽象方法(超类继承的部分),其他抽象方法由继承 AbstractAutowireCapableBeanFactory 的类实现。
Bean的单例模式
对于单例 SingletonBeanRegistry 的接口, DefaultSingletonBeanRegistry 对该进行实现,之后 DefaultSingletonBeanRegistry 会被抽象类 AbstractBeanFactory 继承。现在 AbstractBeanFactory 就是一个非常完整且强大的抽象类了,也能非常好的体现出它对模板模式的抽象定义。

代码结构与解释

在这里插入图片描述

BeanDefinition

BeanDefinition,顾名思义,用于定义bean信息的,包含bean的class类型、构造参数、属性值等信息,每个bean对应一个BeanDefinition的实例。简化BeanDefition仅包含bean的class类型。

public class BeanDefinition {//Class 是一个特殊的类型,它保存有关类的信息private Class beanClass;public BeanDefinition(Class beanClass) {this.beanClass = beanClass;}public Class getBeanClass() {return beanClass;}public void setBeanClass(Class beanClass) {this.beanClass = beanClass;}
}
SingletonBeanRegistry

SingletonBeanRegistry获取单例bean的接口

public interface SingletonBeanRegistry {Object getSingleton(String beanName);}
DefaultSingletonBeanRegistry

DefaultSingletonBeanRegistry实现SingletonBeanRegistry接口
代码解读:
在 DefaultSingletonBeanRegistry 中主要实现 getSingleton 方法,同时实现了一个受保护的 addSingleton 方法,这个方法可以被继承此类的其他类调用。

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {//使用map维护单例beanprivate Map<String, Object> singletonObjects = new HashMap<>();@Overridepublic Object getSingleton(String beanName) {return singletonObjects.get(beanName);}protected void addSingleton(String beanName, Object singletonObject) {singletonObjects.put(beanName, singletonObject);}
}
AbstractBeanFactory
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {@Overridepublic Object getBean(String name) throws BeansException {Object bean = getSingleton(name);if (bean != null) {return bean;}BeanDefinition beanDefinition = getBeanDefinition(name);return createBean(name, beanDefinition);}protected abstract Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException;protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
}

在这里插入图片描述

AbstractBeanFactory 首先继承了 DefaultSingletonBeanRegistry,也就具备了使用单例注册类方法
接下来很重要的一点是关于接口 BeanFactory 的实现,在方法 getBean 的实现过程中可以看到,主要是对单例 Bean 对象的获取以及在获取不到时需要拿到 Bean 的定义做相应 Bean 实例化操作。那么 getBean 并没有自身的去实现这些方法,而是只定义了调用过程以及提供了抽象方法,由实现此抽象类的其他类做相应实现。
后续继承抽象类 AbstractBeanFactory 的类有两个,包括:AbstractAutowireCapableBeanFactory、DefaultListableBeanFactory,这两个类分别做了相应的实现处理

AbstractAutowireCapableBeanFactory

在 AbstractAutowireCapableBeanFactory 类中实现了 Bean 的实例化操作 newInstance,其实这块会埋下一个坑,有构造函数入参的对象怎么处理?可以提前思考
在处理完 Bean 对象的实例化后,直接调用 addSingleton 方法存放到单例对象的缓存中去

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {//实例化@Overrideprotected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {return doCreateBean(beanName, beanDefinition);}protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) {Class beanClass = beanDefinition.getBeanClass();Object bean = null;try {bean = beanClass.newInstance();} catch (Exception e) {throw new BeansException("Instantiation of bean failed", e);}//继承了DefaultSingleBeanRegisty 所以可以调用addSingleton方法 并且成功加入缓存addSingleton(beanName, bean);return bean;}
}
BeanDefinitionRegistry

BeanDefinition注册表接口,定义注册BeanDefintion的方法。

 public interface BeanDefinitionRegistry {/*** 向注册表中注BeanDefinition** @param beanName* @param beanDefinition*/void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
}
DefaultListableBeanFactory

实现Bean的定义与获取

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {beanDefinitionMap.put(beanName, beanDefinition);}@Overrideprotected BeanDefinition getBeanDefinition(String beanName) throws BeansException {BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (beanDefinition == null) {throw new BeansException("No bean named '" + beanName + "' is defined");}return beanDefinition;}
}

DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory 类,也就具备了接口 BeanFactory 和 AbstractBeanFactory 等一连串的功能实现。所以有时候你会看到一些类的强转,调用某些方法,也是因为你强转的类实现接口或继承了某些类。
除此之外这个类还实现了接口 BeanDefinitionRegistry 中的 registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 方法,当然你还会看到一个 getBeanDefinition 的实现,这个方法我们文中提到过它是抽象类 AbstractBeanFactory 中定义的抽象方法。现在注册Bean定义与获取Bean定义就可以同时使用了,是不感觉这个套路还蛮深的。接口定义了注册,抽象类定义了获取,都集中在 DefaultListableBeanFactory 中的 beanDefinitionMap 里

写在最后

Java基础之什么是抽象类
抽象类是一种不能被实例化的类。它主要用于作为其他类的基类,为它们提供一个公共的类型框架和实现部分功能。可继承抽象类进行方法实现
Java基础之抽象类与接口的区别

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin协程的JVM实现源码分析(下)

协程 根据 是否保存切换 调用栈 &#xff0c;分为&#xff1a; 有栈协程&#xff08;stackful coroutine&#xff09;无栈协程&#xff08;stackless coroutine&#xff09; 在代码上的区别是&#xff1a;是否可在普通函数里调用&#xff0c;并暂停其执行。 Kotlin协程&…

66K star!想画出高颜值的流程图,试试这个手绘风开源白板

工作中总是少不了要画画图&#xff0c;不管是开发中绘制流程图&#xff0c;还是设计系统时画出架构图&#xff0c;一款趁手的工具总是少不了。今天我们就来聊聊画图的白板工具。 今天我们推荐的推荐的项目帮你画出手绘风的高颜值图表&#xff0c;目前在GitHub已超过66K Star&a…

redis优化系列(六)

本期分享redis内存过期策略&#xff1a;过期key的处理 Redis之所以性能强&#xff0c;最主要的原因就是基于内存存储。然而单节点的Redis其内存大小不宜过大&#xff0c;会影响持久化或主从同步性能。 可以通过修改配置文件来设置Redis的最大内存&#xff1a; maxmemory 1gb …

DophineScheduler通俗版

1.DophineScheduler的架构 ZooKeeper&#xff1a; AlertServer&#xff1a; UI&#xff1a; ApiServer&#xff1a; 一个租户下可以有多个用户&#xff1b;一个用户可以有多个项目一个项目可以有多个工作流定义&#xff0c;每个工作流定义只属于一个项目&#xff1b;一个租户可…

时空预测网络ST-Resnet 代码复现

ST-ResNet&#xff08;Spatio-Temporal Residual Network&#xff09;是一种用于处理时空数据的深度学习模型&#xff0c;特别适用于视频、时间序列等具有时空结构的数据。下面是一个简单的使用PyTorch搭建ST-ResNet的示例代码。请注意&#xff0c;这只是一个基本的示例&#x…

大模型微调实战笔记

大模型三要素 1.算法&#xff1a;模型结构&#xff0c;训练方法 2.数据&#xff1a;数据和模型效果之间的关系&#xff0c;token分词方法 3.算力&#xff1a;英伟达GPU&#xff0c;模型量化 基于大模型对话的系统架构 基于Lora的模型训练最好用&#xff0c;成本低好上手 提…

【项目日记(三)】内存池的整体框架设计

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你做项目   &#x1f51d;&#x1f51d; 开发环境: Visual Studio 2022 项目日…

(酒驾检测、人脸检测、疲劳检测、模拟口罩数据集制作、防酒驾)-常用的论文所用的python代码总结

汇总&#xff1a; 学习感悟&#xff1a;如果小白建议一行一行的Debug,看够一定量的代码&#xff0c;自己就自然顺手写代码了。汇总上传的东西用在自己电脑上一般都需要适当修改的。 20&#xff0c;水平翻转图片 19&#xff0c;颜色空间装换HSV对比演示 18&#xff0c;光照补…

永赢基金引入微签电子签章系统实现审批签章电子化

永赢基金管理有限公司采用微签电子签章系统&#xff0c;作为进一步推动办公自动化转型的解决方案。微签在审批签署方面的显著优势&#xff0c;帮助永赢基金有效解决了原有OA系统无法满足电子文件全程电子化、签章不落地的问题&#xff0c;实现办公效率翻倍。 公司概况 永赢基金…

PaddleOCR实现对表格的提取

1、背景 PaddleOCR: 基于飞桨的OCR工具库&#xff0c;包含总模型仅8.6M的超轻量级中文OCR&#xff0c;单模型支持中英文数字组合识别、竖排文本识别、长文本识别。同时支持多种文本检测、文本识别的训练算法。对pdf/word里的表格中识别出有效信息具有重要意义&#xff0c;比如…

2. SpringBoot3 实战之用户模块接口开发

文章目录 开发模式和环境搭建开发模式环境搭建 1. 用户注册1.1 注册接口基本代码编写1.2 注册接口参数校验 2. 用户登录2.1 登录接口基本代码编写2.2 登录认证2.2.1 登录认证引入2.2.2 JWT 简介2.2.3 登录功能集成 JWT2.2.4 拦截器 3. 获取用户详细信息3.1 获取用户详细信息基本…

【QT+QGIS跨平台编译】之四:【libSSH2+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、libSSH2介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、libSSH2介绍 libSSH2是一个开源的C函数库&#xff0c;用来实现SSH2协议。 SSH(Secure SHell)到目前为止有两个不兼容的版本——SSH1和SSH2。 SSH2避免了RSA的专利问题&#xff0c;并修补了CRC…