手写Spring系列【一】IOC的简单实现笔记

news2024/11/19 20:34:50

前言
👏作者简介:我是笑霸final,一名热爱技术的在校学生。
📝个人主页:个人主页1 || 笑霸final的主页2
📕系列专栏:项目专栏
📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏

🔥在这里说一下参考作者的博客地址:https://bugstack.cn 作者叫小傅哥,教程的名字叫《手撸Spring》,也算个版权声明以及宣传吧~

目录

  • 一源码目录和类关系
  • 二、简单的Bean定义 BeanDefinition
  • 三、定义单例注册接口
    • 3.1 SingletonBeanRegistry 接口
    • 3.2 DefaultSingletonBeanRegistry
  • 四、定义Bean 工厂 BeanFactory
    • 4.1 抽象类Bean工厂模板AbstractBeanFactory
    • 4.2 实例化Bean类(AbstractAutowireCapableBeanFactory)
  • 五、DefaultListableBeanFactory核心类实现
  • 六、总结

一源码目录和类关系

项目目录
在这里插入图片描述
类关系
在这里插入图片描述
详细关系图
在这里插入图片描述
查看原图===》 点此
接下来 我们就实现上面的类!!!

二、简单的Bean定义 BeanDefinition

BeanDefinition的实现类用于描述Spring中的一个应该被实例化的bean的各种性质,包括bean的属性值,构造函数,方法等等。在容器中,这些Bean的定义用BeanDefinition对象来表示,包含以下元数据: 1. 全限定类名, 通常是Bean的实际实现类; 2. Bean行为配置元素,它们 展开后包含了该bean所具有的各种属性、注入方式、销毁方式等等。

这里我们先实现简单的一个BeanDefinition

public class BeanDefinition {

    // 定义成 Class 这样就可以把 Bean 的实例化操作放到容器中处理了。
    private Class beanClass;
    public BeanDefinition(Class beanClass){
        this.beanClass = beanClass;
    }
    public Class getBeanClass() {
        return beanClass;
    }
    public void setBeanClass(Class beanClass){
        this.beanClass = beanClass;
    }
}

三、定义单例注册接口

3.1 SingletonBeanRegistry 接口

主要定义了一个获取单例对象的接口

public interface SingletonBeanRegistry {
    //得到 单例bean
    Object getSingleton(String beanName);
}

3.2 DefaultSingletonBeanRegistry

实现Object getSingleton(String beanName);的同时 自己还添加addSingleton() 方法
stringObjectMap 用来保存单例对象

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
    //容器 存放单例bean
    private Map<String,Object> stringObjectMap = new HashMap<>();

    @Override
    public Object getSingleton(String beanName) {
        return stringObjectMap.get(beanName);
    }

    protected void addSingleton(String beanName , Object singletonObject){
        stringObjectMap.put(beanName,singletonObject);
    }
}

四、定义Bean 工厂 BeanFactory

public interface  BeanFactory {
    Object getBean(String name);
}

由 AbstractBeanFactory 抽象类实现接口的 getBean 方法
目前的 BeanFactory 仍然是非常简化的实现、后续笔记会逐步完善此类

4.1 抽象类Bean工厂模板AbstractBeanFactory

AbstractBeanFactory 抽象Bean工厂
此类 继承了 DefaultSingletonBeanRegistry 类 此类方法都实现了
实现了 BeanFactory 接口 实现getBean()方法来得到Bean
新增加了BeanDefinition()createBean()两个抽象方法

public abstract class AbstractBeanFactory 
								extends DefaultSingletonBeanRegistry
								implements BeanFactory {
    @Override
    public Object getBean(String name) {
        //调用继承DefaultSingletonBeanRegistry实现的方法
        Object bean = getSingleton(name);
        if(bean != null){
            return bean;
        }
        BeanDefinition beanDefinition = getBeanDefinition(name);
        return createBean(name,beanDefinition);
    }

    protected abstract BeanDefinition getBeanDefinition(String beanName) ;
    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition);

}

getBean(String name):获取单例Bean
当第一次进入此方法 getSingleton(name);返回空 就会跳过 if 方法从而去创建 BeanDefinition对象然后由BeanDefinition的信息来创建Bean对象 当然此类并不实现这两个方法

4.2 实例化Bean类(AbstractAutowireCapableBeanFactory)

AbstractAutowireCapableBeanFactory 抽象自动装配Bean工厂 :创建对象
继承了 AbstractBeanFactory类 并实现 抽象方法createBean()
createBean() 根据beanDefinition来创建单例对象

public abstract class AbstractAutowireCapableBeanFactory extends  AbstractBeanFactory{

    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition) {
        Object bean = null;
        try{
            bean = beanDefinition.getBeanClass().newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //此方法是DefaultSingletonBeanRegistry中的 保存单例bean
        addSingleton(beanName,bean);
        return bean;
    }
}

五、DefaultListableBeanFactory核心类实现

实现BeanDefinitionRegistry接口中的registerBeanDefinition() 把 一个BeanDefinition 对象保存至容器。
继承AbstractAutowireCapableBeanFactory 类 并实现 getBeanDefinition()此方法是 AbstractBeanFactory中定义的 用来得到一个BeanDefinition

public class DefaultListableBeanFactory 
											extends  AbstractAutowireCapableBeanFactory 
											implements BeanDefinitionRegistry {


    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();

    @Override
    protected BeanDefinition getBeanDefinition(String beanName) {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) throw new BeansException("No bean named '" + beanName + "' is defined");
        return beanDefinition;
    }

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
    }
}

六、总结

在这里插入图片描述

先把把 类信息 添加到 BeanDefinition
DefaultListableBeanFactory类是核心类 此类把我们的BeanDefinition注册到BeanDefinition对象池中
然后再 得到Bean对象(根据BeanDefinition的信息来创建bean)
bean对象实在第一次调用getBean()创建的

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uni-app:文本超出部分用省略号表示

效果 前 后 核心代码 white-space: nowrap; /* 强制不换行 */ text-overflow: ellipsis; /* 超过部分省略号代替 */ overflow: hidden; /* 必须同时设置overflow:hidden才能生效 */ 完整代码 <template><view><view class"all_style"><view c…

「才得吹嘘身渐稳」,也来谈谈大模型

要问2023年的科技领域什么消息最博人眼球&#xff0c;那么22年底发布、23年迅速跻身顶流的ChatGPT一定占有一席之地。随着ChatGPT的“爆火出圈”&#xff0c;国内外大厂纷纷布局「生成式语言模型」研发赛道&#xff0c;各类应用也如雨后春笋般层出不穷&#xff0c;让人眼花缭乱…

SpringBoot的配置文件——.yml和.properties

目录 1. Spring Boot 配置文件的使用场景 2. 配置文件的两种格式 2.0 特殊说明&#xff1a; 2.1 .properties 2.1.1 格式 2.2.2 缺陷 2.2.3 解决中文乱码的问题 2.2 .yml 2.2.3 格式 配置数据库连接 注意转义字符 ​编辑 ​编辑 配置null 配置对象 从.yml读取文件举例 Stud…

v-on/@ 事件处理指令修饰符-stop、prevent、once

v-on/事件修饰符&#xff1a; 一、.stop 阻止单机事件继续传播 event.stopProgagetion() eg: <h3>事件修饰符</h3> <div click"todo"> <div click.stop"doThis"> 单机事件会继续传递 </div> </div> 点击 单机事…

【Java 进阶篇】Java Web 编写注册页面案例

当涉及到创建一个Java Web注册页面时&#xff0c;你将需要涵盖很多不同的主题&#xff0c;包括HTML、CSS、Java Servlet和数据库连接。在这篇文章中&#xff0c;我们将详细介绍每个步骤&#xff0c;以帮助你创建一个完整的注册页面。 1. 介绍 注册页面是许多Web应用程序的关键…

STM32标准库代码转为LL库代码-详解

概述 由于标准库&#xff0c;ST公司逐步不再维护&#xff0c;比较老旧的项目&#xff0c;都是使用标准库来开发&#xff0c;如果想使用LL库&#xff0c;需要借助《SPL2LL转换器》实现。 1、LL库简介 LL库&#xff0c;即STM32Cube Low-Layer&#xff0c;也叫Cube LL、Cube底层…

文件上传 [极客大挑战 2019]Upload 1

题目来源&#xff1a;buuctf [极客大挑战 2019]Upload 1 打开题目 是一道文件上传题 我们上传png和jpg格式的一句话木马上去看看 上传失败了&#xff0c;应该是在后端也对我们的文件内容进行了检测&#xff0c;检测到我们的一句话木马里面包含<? 那我们重新换个一句话木…

【软件工程】常见软件过程模型及其优缺点

软件过程模型 1. 瀑布模型2. V模型3. 原型模型4. 增量模型5. 螺旋模型6. 喷泉模型 1. 瀑布模型 描述&#xff1a; 瀑布模型是将软件开发划分为不同的阶段&#xff0c;只有上一个阶段完成了才能进入到下一个阶段&#xff0c;也就是按照需求分析、设计、实现、测试、运行和维护这…

UML类图是什么?怎么画?

在软件开发和系统设计领域&#xff0c;UML&#xff08;Unified Modeling Language&#xff09;类图是一种强大的工具&#xff0c;用于可视化和表示软件系统的结构和关系。如果你曾经在软件开发中遇到过“UML类图是什么&#xff1f;”这个问题&#xff0c;那么你来对地方了。本文…

简要归纳UE5 Lumen全局光照原理

一、Jim kajiya老爷子的渲染方程&#xff1a; 求全局光照就是求解渲染方程&#xff0c;我们将两边都有未知数的渲染方程变换成离散形式&#xff1a; 更形象的描述这个离散的渲染方程&#xff1a; 要给每个三角形着色就得先判断光线有没有和它相交&#xff0c;以下是求光线和三…

3D 生成重建006-3DFuse 形状引导一致性的文生3d的方法

3D生成重建006-3DFuse 形状引导一致性的文生3d的方法 文章目录 0 论文介绍1 论文方法1.1 semantic code1.2 稀疏深度信息PointE1.3 lora部分 2 效果 0 论文介绍 在004-DreamFusion and SJC 中dreamfusion提到将2D观测结果“提升”到3D世界的任务本质上是模糊的&#xff0c;并…

1810_spacemacs缺少evil-unimpaired以及evil-ediff安装失败解决

全部学习汇总&#xff1a; GreyZhang/editors_skills: Summary for some common editor skills I used. (github.com) 安装的时候遇到evil-unimpaired找不到的问题&#xff0c;查了一下网络上很多人都遇到这样的问题&#xff0c;但是问题千奇八怪。更要命的可能是我遇到的提示跟…

【ARM AMBA5 CHI 入门 12.1 -- CHI 链路层详细介绍 】

文章目录 CHI 版本介绍1.1 CHI 链路层介绍1.1.1 Flit 切片介绍1.1.2 link layer credit(L-Credit)机制1.1.3 Channel1.1.4 Port1.1. RN Node 接口定义1.1.6 SN Node 接口定义1.2 Channel interface signals1.2.1 Request, REQ, channel1.2.2 Response, RSP, channel1.2.3 Snoop…

一个完整的初学者指南Django-part2

介绍 欢迎来到 Django 教程的第二部分&#xff01;在上一课中&#xff0c;我们安装了项目所需要的一切软件&#xff0c;希望你们在学习这篇文章之前&#xff0c;安装了 Python 3.6&#xff0c;并且在虚拟环境中运行Django 1.11。因为&#xff0c;在本篇文章中&#xff0c;我们…

并购交易:埃克森美孚商谈以250美元/股的价格收购先锋自然资源

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;埃克森美孚(XOM)正在商谈以250美元/股的价格收购先锋自然资源(PXD)。 彭博社援引知情人士的消息报道称&#xff0c;一项全股票交易最早可能于周三宣布。按照每股250美元的价格计算&#xff0c;先锋…

【动态规划】198. 打家劫舍、213. 打家劫舍 II、337. 打家劫舍 III

提示&#xff1a;努力生活&#xff0c;开心、快乐的一天 文章目录 198. 打家劫舍&#x1f4a1;解题思路&#x1f914;遇到的问题&#x1f4bb;代码实现&#x1f3af;题目总结 213. 打家劫舍 II&#x1f4a1;解题思路&#x1f914;遇到的问题&#x1f4bb;代码实现&#x1f3af;…

postman发送POST请求,模拟请求头界面的响应信息

postman发送POST请求 示例&#xff1a;微信公众平台创建用户标签接口&#xff0c;业务操作如下&#xff1a; 1、打开微信公众平台&#xff0c;微信扫码登录&#xff1a;https://mp.weixin.qq.com/debug/cgi-bin/sandbox?tsandbox/login 同时&#xff0c;我也为大家准备了一份…

求二叉树节点的个数——后序遍历

之前我们已经学习了二叉树前中后序的遍历&#xff0c;在次基础上我们利用遍历来求二叉树的节点个数 利用变量来计数&#xff1a; int BinaryTreeSize(BTNode* root) {int size 0;if (root NULL){return 0;}else{size;}BinaryTreeSize(root->left);BinaryTreeSize(root-&…

Spring5应用之事务属性

作者简介&#xff1a;☕️大家好&#xff0c;我是Aomsir&#xff0c;一个爱折腾的开发者&#xff01; 个人主页&#xff1a;Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏&#xff1a;Spring5应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言事务…

指针拔尖(2)(巩固提高,全网最牛,包会,看不懂带电脑来找我)

文章目录 前言变量的声明 一、函数指针二、函数指针数组三、指向函数指针数组的指针四、 回调函数总结 前言 提示&#xff1a;本章是指针拔尖系列的终章&#xff0c;有四大知识点。 一、函数指针 二、函数指针数组 三、指向函数指针数组的指针 四、回调函数 但学习这些知识点我…