【Spring IOC】实现一个简单的 Spring 容器

1. 理解知识

Spring 容器的作用

Spring 容器是Spring的核心,用来管理Bean对象的。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。

Bean 对象的管理

当一个 Bean 对象交给 Spring 容器管理时,这个 Bean 对象会被拆解成多个配置项,存储在 Bean 的定义中。

这种拆解操作使得对象更加模块化和解耦,从而更容易被 Spring 容器管理和操作。例如,Spring 容器可以轻松处理循环依赖等问题,确保应用的稳定性和高效性。

2. 设计

在这里插入图片描述

模拟 Spring 容器的设计

在模拟 Spring 框架时,首先需要创建一个 Spring 容器,这是 Spring 框架的核心组件。所有 Bean 都存储在容器内,并通过控制反转(IOC)技术进行管理。

Spring 容器本质上是一个 Bean 工厂(BeanFactory),负责 Bean 的实例化、获取和销毁。ApplicationContext 是 Spring 容器的一个典型实现类,它提供了基本的 Bean 管理功能。

凡是可以存放数据的具体数据结构实现,都可以称之为容器。例如:ArrayList、LinkedList、HashSet等,但在 Spring Bean 容器的场景下,我们需要一种可以用于存放和名称索引式的数据结构,所以选择 HashMap 是最合适不过的。

3. 实现

在这里插入图片描述
BeanDefinition:通常由Spring容器在启动过程中根据配置信息或注解生成,是Sping Ioc容器管理的核心数据结构之一,用于保存Bean的配置和属性
在这里插入图片描述

第一步

创建BeanFactory(Bean工厂)

public class BeanFactory {
    // 泛型:<String, BeanDefinition> 表示键是 String 类型,值是 BeanDefinition 类型。
    // ConcurrentHashMap 是线程安全的哈希表实现,用于存储 bean 的定义信息。
    private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

    public Object getBean(String name) {
        // 通过 name -> 获取 bean
        // 这里的get方法是 Map接口提供的,返回的是一个BeanDefinition对象
        return beanDefinitionMap.get(name).getBean();
    }

    // 通过 name 和 BeanDefinition 对象注册
    public void registerBeanDefinition(String name, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(name, beanDefinition);
    }
}

这里get方法是ConcurrentHashMap 内自带的方法,通过键返回值
在这里插入图片描述

创建BeanDefinition( Bean定义)

public class BeanDefinition {
    // Bean 对象
    private Object bean;
    // 初始化Bean并赋值
    public BeanDefinition(Object bean) {
        this.bean = bean;
    }
    // 获取Bean
    public Object getBean() {
        return bean;
    }
}

第二步

创建UserService测试对象

public class UserService {

   public void queryUserInfo(){
      System.out.println("查询用户信息");
   }

}

创建测试用例

public class ApiTest {

    @Test
    public void test_BeanFactory(){
        // 1.初始化 BeanFactory
        BeanFactory beanFactory = new BeanFactory();

        // 2.注册 bean
        // 构造方法传入UserService对象
        BeanDefinition beanDefinition = new BeanDefinition(new UserService());
        // 通过BeanDefinition的registerBeanDefinition去注册bean 
        // 注意泛型 String,Beandefinition
        beanFactory.registerBeanDefinition("userService", beanDefinition);

        // 3.获取 bean
        UserService userService = (UserService) beanFactory.getBean("userService");
        userService.queryUserInfo();
    }
}

第三步

运行测试用例

查询用户信息

Process finished with exit code 0

总结流程

一个 Spring 容器的注册,归根结底是通过 BeanDefinition 进行注册的,再通过 BeanFactory 进行管理分配,
一个 BeanFactory 可以管理多个 BeanDefinition
在这里插入图片描述

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

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

相关文章

非线性数据结构之图

一、有向图&#xff08;Directed Graph&#xff09; 1. 定义 有向图是一个由顶点&#xff08;节点&#xff09;和有方向的边&#xff08;弧&#xff09;组成的图。在有向图中&#xff0c;每条边都有一个起点和一个终点&#xff0c;表示从一个顶点到另一个顶点的关系。 2. 特…

【算法】——滑动窗口专题

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;长度最小的子数组 二&#xff1a;无重复字符的最长子串 三&#xff1a;最大连续1的个…

目前主流的人工智能学习框架有哪些?

随着人工智能&#xff08;AI&#xff09;技术的蓬勃发展&#xff0c;越来越多的AI学习框架相继推出&#xff0c;成为开发者、研究人员和企业构建机器学习&#xff08;ML&#xff09;和深度学习&#xff08;DL&#xff09;模型的首选工具。AI学习框架不仅提供了丰富的工具库和函…

揭开自然语言处理(NLP)的神秘面纱

时间&#xff1a;2024年 11月 05日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 微信&#xff1a;wei_wei10 音频&#xff1a;喜马拉雅 大家好&#xff0c;欢迎来到“小蒋聊技术” &#xff0c;我是小蒋&#xff01;。小蒋最近在学习清华大模型课程&…

C#:强大而优雅的编程语言

在当今的软件开发领域&#xff0c;C#作为一种广泛应用的编程语言&#xff0c;以其强大的功能、优雅的语法和丰富的生态系统&#xff0c;受到了众多开发者的喜爱。本文将深入探讨 C#的各个方面&#xff0c;展示它的魅力和优势。 一、C#的历史与发展 C#是由微软公司开发的一种面…

SQL CASE表达式与窗口函数

CASE 表达式是一种通用的条件表达式&#xff0c;类似于其他编程语言中的if/else语句。 窗口函数类似于group by&#xff0c;但是不会改变记录行数&#xff0c;能扫描所有行&#xff0c;能对每一行执行聚合计算或其他复杂计算&#xff0c;并把结果填到每一行中。 1 CASE 表达式…

C++之位算法

位算法 常见位运算总结 位1的个数 给定一个正整数 n&#xff0c;编写一个函数&#xff0c;获取一个正整数的二进制形式并返回其二进制表达式中 设置位 的个数&#xff08;也被称为汉明重量&#xff09;。 示例 1&#xff1a; 输入&#xff1a;n 11 输出&#xff1a;3 解释…

【OJ题解】C++实现字符串大数相乘:无BigInteger库的字符串乘积解决方案

&#x1f984;个人主页: 起名字真南 &#x1f984;个人专栏:【数据结构初阶】 【C语言】 【C】 【OJ题解】 目录 1. 引言2. 题目分析示例&#xff1a; 3. 解题思路4. C代码实现5. 代码详解6. 时间和空间复杂度分析7. 边界情况分析8. 总结 1. 引言 在开发中&#xff0c;有时我们…

用Python将PDF表格提取到文本、CSV和Excel文件中

从PDF文档中提取表格并将其转换为更易于处理的格式&#xff08;如文本、CSV和Excel文件&#xff09;&#xff0c;是数据分析和信息管理中的常见需求。此过程可显著简化表格数据的处理&#xff0c;使数据的操作、分析和与其他数据集的集成更加便捷。无论是财务报表、研究论文&am…

如何在 IntelliJ IDEA 中调整 `Ctrl+/` 快捷键生成注释的位置

前言 在使用 IntelliJ IDEA 编写代码时&#xff0c;注释是代码可读性和维护性的重要组成部分。IDEA 提供了快捷键 Ctrl/ 用于快速生成单行注释。然而&#xff0c;默认情况下&#xff0c;使用此快捷键生成的注释会出现在行首&#xff0c;导致注释与代码之间存在较大的空格&…

深入理解对象池 sync.Pool

文章目录 前言应用使用源码走读数据结构Get获取对象Put归还对象poolDeque分析GC时 总结 前言 当多个 goroutine 都需要创建同⼀种对象的时候&#xff0c;如果 goroutine 数量过多&#xff0c;导致对象的创建剧增&#xff0c;进⽽导致 GC 压⼒增大。形成下面的恶性循环&#xf…

项目管理(软设软考高频)

一、进度管理 1.Gantt图 2.PERT图 二、风险管理 三、沟通管理 四、成本管理

在Java中,实现数据库连接通常使用JDBC

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技巧(编写中……&#xff09; 5、面经吐血整理的 面试技…

gradle下载的jar包,源码出现Decompiled .class file, bytecode version

如下是问题截图 问题产生原因&#xff1a; gradle依赖下载只下载了jar包&#xff0c;这导致idea在读取jar包时&#xff0c;需要通过Fernflower技术对jar包进行反编译&#xff0c;而反编译过程中只会保留源码信息&#xff0c;因此注释等额外信息全部丢失 解决方案&#xff1a…

[357]基于springboot的中小型制造企业质量管理系统

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…

SAP(PP生产制造)拆解工单业务处理

1、BOM维护 要拆解的成品或半成品要和原成品、半成品BOM一致 2、创建拆解工单 CO01选择拆解工单的类型&#xff0c;以及填写拆解的物料和拆解工厂 维护工单组件 注意&#xff1a; 1、拆解入库组件的数量需要维护为负数 2、拆解工单投料组件数量维护为正数 3、拆解工单收发…

NavVis LX系列产品典型应用—现有住宅装修改造-沪敖3D

现有住宅装修改造项目的 数据捕捉和测量技术 当Jay Ure着手翻新和美化自己的新家时&#xff0c;他敏锐地发现这是现场测试NavVis VLX的绝佳机会。 为了全面评估&#xff0c;他聘请了一位工程师&#xff0c;采用传统的全站仪技术进行地形测绘。之后&#xff0c;他用移动扫描设…

【初阶数据结构篇】链式结构二叉树(续)

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

qt QTabWidget详解

1、概述 QTabWidget是Qt框架中的一个控件&#xff0c;它提供了一个标签页式的界面&#xff0c;允许用户在不同的页面&#xff08;或称为标签&#xff09;之间切换。每个页面都可以包含不同的内容&#xff0c;如文本、图像、按钮或其他小部件。QTabWidget非常适合用于创建具有多…

Linux系统基础-多线程超详细讲解(5)_单例模式与线程池

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Linux系统基础-多线程超详细讲解(5)_单例模式与线程池 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&a…