手写Spring:第2章-创建简单的Bean容器

文章目录

  • 一、目标:创建简单的Bean容器
  • 二、设计:创建简单的Bean容器
  • 三、实现:创建简单的Bean容器
    • 3.0 引入依赖
    • 3.1 工程结构
    • 3.2 创建简单Bean容器类图
    • 3.3 Bean定义
    • 3.4 Bean工厂
  • 四、测试:创建简单的Bean容器
    • 4.1 用户Bean对象
    • 4.2 单元测试
  • 五、总结:创建简单的Bean容器

一、目标:创建简单的Bean容器

💡 Spring Bean 容器是什么?

  • Spring 包含并管理应用对象的配置和生命周期,在这个意义上它是一种用于承载对象的容器
    • 你可以配置你的每个 Bean 对象是如何被创建的。
    • 这些 Bean 可以创建一个单独的实例或者每次需要时都生成一个新的实例,以及它们是如何相互关联构建和使用的。
  • 如果一个 Bean 对象交给 Spring 容器管理,那么这个 Bean 对象就应该以类似零件的方式被拆解后存放到 Bean 的定义中。
    • 这样相当于一种把对象解耦的操作,可以由 Spring 更加容易的管理,就像处理循环依赖等操作。
  • 当一个 Bean 对象被定义存放以后,再由 Spring 统一进行装配,这个过程包括:Bean 的初始化、属性填充等。
    • 最终我们就可以完整的使用一个 Bean 实例化后的对象了。
  • 目标:定义一个简单的 Spring 容器,用于定义、存放和获取 Bean 对象。

二、设计:创建简单的Bean容器

💡 简单的 Spring Bean 容器如何实现?

  • 凡是可以存放数据的具体数据结构实现,都可以称之为容器
    • 例如:ArrayListLinkedListHashSet 等。
    • 但在 Spring Bean 容器的场景下,我们需要一种可以用于存放和名称索引式的数据结构,HashMap 是最合适的。
  • HashMap:是一种基于扰动函数、负载因子、红黑树转换等技术内容,形成的拉链寻址的数据结构。
    • 它能让数据更加散列的分布在哈希桶以及碰撞时形成的链表和红黑树上。
    • 它的数据结构会尽可能最大限度的让整个数据读取的复杂度在 O(1)~O(Logn)~O(n) 之间。
    • 当日在极端情况下也会有 O(n) 链表查找数据较多的情况,不过我们经过10万数据的扰动函数再寻址验证测试,数据会均匀的散列在各个哈希桶索引上。
    • 所以 HashMap 非常适合用在 Spring Bean 的容器实现上。
  • 一个简单的 Spring Bean 容器实现,还需 Bean 的定义、注册、获取三个基本步骤。

在这里插入图片描述

  • 定义BeanDefinition,它会包括 singleton、prototype、BeanClassName 等。目前初步实现一个 Object 类型用于存放对象。
  • 注册:这个过程就相当于我们把数据存放到 HashMap 中,只不过现在 HashMap 存放的是定义了的 Bean 对象信息。
  • 获取:最后就是获取对象,Bean 的名字就是 keySpring 容器初始化好 Bean 以后,就可以直接获取了。

三、实现:创建简单的Bean容器

3.0 引入依赖

pom.xml

<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency>
</dependencies>

3.1 工程结构

spring-step-01
|-src|-main|	|-java|		|-com.lino.springframework|			|-BeanDefinition.java|			|-BeanFactory.java|-test|-java|-com.lino.springframework.test|-bean|	|-UserService.java|-ApiTest.java

3.2 创建简单Bean容器类图

在这里插入图片描述

  • Spring Bean 容器的整个实现内容非常简单,也仅仅是包括了一个简单的 BeanFactoryBeanDefinition
    • 这里的类名称是与 Spring 源码中一致,只不过现在的类实现会相对来说更简化一些,在后续的实现再继续添加内容。
    • BeanFactory:用于定义 Bean 实例化信息,现在的实现是一个 Object 存放对象。
    • BeanDefinition:代表了 Bean 对象的工厂,可以存放 Bean 定义到 Map 中以及获取。

3.3 Bean定义

BeanDefinition.java

package com.lino.springframework;/*** @description: Bean 对象信息定义*/
public class BeanDefinition {/*** bean对象*/private Object bean;public BeanDefinition(Object bean) {this.bean = bean;}public Object getBean() {return bean;}
}
  • 目前的 Bean 定义中,只有一个 Object 用于存放 Bean 对象。
  • 在后续的实现中会逐步完善 BeanDefinition 相关属性的填充。
    • 例如:SCOPE_SINGLETON、SCOPE_PROTOTYPE、ROLE_APPLICATION、ROLE_SUPPORT、ROLE_INFRASTRUCTURE 以及 Bean Class 信息。

3.4 Bean工厂

BeanFactory.java

package com.lino.springframework;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** @description: 简单的 Bean 工厂*/
public class BeanFactory {/*** bean对象Map*/private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();public Object getBean(String name) {return beanDefinitionMap.get(name).getBean();}public void registerBeanDefinition(String name, BeanDefinition beanDefinition) {beanDefinitionMap.put(name, beanDefinition);}
}
  • Bean 工厂的实现中,包括了 Bean 的注册,这里注册的是 Bean 的定义信息。同时在这个类中还包括了获取 Bean 的操作。
  • 目前的 BeanFactory 仍然是简化的实现,但这种简化的实现内容也是整个 Spring 容器中关于 Bean 使用的最终体现结果。
    • 只不过实现过程只展示出基本的核心原理。

四、测试:创建简单的Bean容器

4.1 用户Bean对象

UserService.java

package com.lino.springframework.test.bean;/*** @description: 模拟用户 Bean 对象*/
public class UserService {/*** 查询用户信息*/public void queryUserInfo() {System.out.println("查询用户信息");}
}
  • 定义一个 UserService 对象。

4.2 单元测试

ApiTest.java

package com.lino.springframework.test;import com.lino.springframework.BeanDefinition;
import com.lino.springframework.BeanFactory;
import com.lino.springframework.test.bean.UserService;
import org.junit.Test;/*** @description: 测试类*/
public class ApiTest {@Testpublic void test_BeanFactory() {// 1.初始化 BeanFactoryBeanFactory beanFactory = new BeanFactory();// 2.注入beanBeanDefinition beanDefinition = new BeanDefinition(new UserService());beanFactory.registerBeanDefinition("userService", beanDefinition);// 3.获取beanUserService userService = (UserService) beanFactory.getBean("userService");userService.queryUserInfo();}
}
  • 在单元测试中主要包括 初始化 Bean 工厂、注册 Bean、获取 Bean 三个步骤。
  • Bean 的注册中,这里是直接把 UserService 实例化后作为入参传递给 BeanDefinition 的,在后续的陆续实现中,这部分会放入 Bean 工厂中实现。

测试结果

查询用户信息
  • 通过测试结果看是正常通过的。

五、总结:创建简单的Bean容器

  • 整篇关于 Spring Bean 容器的一个雏形就已经实现完成了。
  • 相对于一个知识的学习来说,写代码只是最后的步骤,往往整个思路、设计、方案,才更重要,只要你知道了因为什么,所以什么,才能让你有一个真正的理解。

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

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

相关文章

go-zero直连与etcd服务注册中心

go-zero中直连方式 在使用grpc是最重要的就是pb文件了&#xff0c;生成的pb文件&#xff0c;通过pb文件可以生成grpc的客户端和服务端&#xff0c;那么客户端和服务端就可以直连了&#xff0c;再次基础上可以引入etcd实现服务注册。 所有的代码都需要开发者编写&#xff0c;包…

Stable Diffuse 之 本地环境部署 WebUI 进行汉化操作

Stable Diffuse 之 本地环境部署 WebUI 进行汉化操作 目录 Stable Diffuse 之 本地环境部署 WebUI 进行汉化操作 一、简单介绍 二、汉化操作 附录&#xff1a; 一、Install from URL 中出现 Failed to connect to 127.0.0.1 port 7890: Connection refused 错误&#xf…

基于微信小程序美食菜品预订点餐预约系统uniapp+vue

点餐预约系统主要是为了提高用户的工作效率和更方便快捷的满足用户&#xff0c;更好存储所有数据信息及快速方便的检索功能&#xff0c;对点餐预约系统的各个模块是通过许多今天的发达点餐预约系统做出合理的分析来确定考虑用户的可操作性&#xff0c;遵循开发的系统优化的原则…

网络安全概述

从今天开始&#xff0c;我将开启一个网络安全的小课堂&#xff0c;分享一些网络安全方面的相关知识点&#xff0c;大家可以一起学习&#xff0c;争取对网络安全、网络攻防有一定的认识&#xff0c;今天是第一讲网络安全概述&#xff0c;来简单介绍一下网络安全。 1 网络安全的…

数据结构零基础入门篇(C语言实现)

前言&#xff1a;数据结构属于C学习中较难的一部分&#xff0c;对应学习者的要求较高&#xff0c;如基础不扎实&#xff0c;建议着重学习C语言中的指针和结构体&#xff0c;万丈高楼平地起。 目录&#xff1a; 一&#xff0c;链表 1&#xff09;单链表的大致结构实现 2&…

IDEA插件Mybatis Log Plugin的安装及其使用教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 插件概述 Mybatis Log Plugin插件用于查看Mybatis所执行的完整SQL语句。在此教程中详细介绍IDEA插件Mybatis Log Plugin的安装及其使用。 安装过程 请搜索并安装Mybatis …

强大的JTAG边界扫描(3):常用边界扫描测试软件

文章目录 1. 功能强大的XJTAG2. 小巧简洁的TopJTAG3. TopJTAG安装4. TopJTAG基本使用 本文介绍两款常用的边界扫描测试软件&#xff1a;XJTAG和TopJTAG&#xff0c;前者收费、功能强大&#xff0c;后者免费&#xff08;和谐后&#xff09;&#xff0c;功能简洁。 如果只是要进…

springdoc-openapi-ui 整合 knife,多模块分组,脚手架

pom文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.o…

【VS Code插件开发】常见自定义命令(七)

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域优质作者、阿里云专家博主&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4e2; 资料领取&#xff1a;前端…

FANUC机器人电气控制柜内部硬件电路和模块详细介绍

FANUC机器人电气控制柜内部硬件电路和模块详细介绍 PSU电源单元 通过背板传输了如下电源 +5 +2.0V +3.3 +24v +24E +15V -15V 主板--接口描述: 主板内部结构: 面板电路板: 引申一下 KM21 与 KM22 的作用它们分别接至操作面板上上的急停按

分库分表实战

数据分片与分片算法 分库分表的第一性原理&#xff0c;那就是&#xff1a;存储容量和性能容量。只有对核心业务表才会精心进行分库分表的设计。 首先我们了解一下数据分片是什么意思&#xff1f; 本质上的分库分表不就是数据分片吗&#xff1f;定义就是&#xff1a;按照某个…

Flask狼书笔记 | 05_数据库

文章目录 5 数据库5.1 数据库的分类5.2 ORM5.3 使用Flask_SQLAlchemy5.4 数据库操作5.5 定义关系5.6 更新数据库表5.7 数据库进阶小结 5 数据库 这一章学习如何在Python中使用DBMS&#xff08;数据库管理系统&#xff09;&#xff0c;来对数据库进行管理和操作。本书使用SQLit…

算法通关村14关 | 堆在数组中找第k大的元素应用

1. 在数组中找第k大元素 题目 LeetCode215&#xff1a;给定整数数组nums和整数k&#xff0c;请返回数组中第k个最大的元素&#xff0c; 思路 解题思路用三个&#xff0c;选择法&#xff0c;堆查找和快速排序。 我们选择用大堆小堆解决问题&#xff0c;“找最大用小堆&#xff…

【JS面试题】如何通过闭包漏洞在外部修改函数中的变量

✍️ 作者简介: 前端新手学习中。 &#x1f482; 作者主页: 作者主页查看更多前端教学 &#x1f393; 专栏分享&#xff1a;css重难点教学 Node.js教学 从头开始学习 ajax学习 前端面试题 文章目录 什么是闭包例 如何在函数外部修改闭包中变量 什么是闭包 闭包这个东西对新…

animate.css与vue中的v-if/v-show如何一起使用

第一步:在已有的vue项目中安装animate.css npm install animate.css --save第二步&#xff1a;在 main.js 引入 import animate.css第三步&#xff1a;如果在vue中使用了v-if 或者v-show 的话就不能直接在元素上加入animate的class。我们应该在v-if/v-show的元素外层添加tran…

一个新工具 nolyfill

名字的意思&#xff0c; 我自己的理解 no(po)lyfill 正如它的名字, 不要再用补丁了, 当然这里说的是过时的补丁。 polyfill 是补丁的意思 为什么要用这个插件 文档原文: 当您通过安装最新的 Node.js LTS 来接受最新的功能和安全修复时&#xff0c;像eslint-plugin-import、…

基于Java+SpringBoot+Vue前后端分离高校专业实习管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

项目实战:ES的增加数据和查询数据

文章目录 背景在ES中增加数据新建索引删除索引 在ES中查询数据查询数据总数量 项目具体使用&#xff08;实战&#xff09;引入依赖方式一&#xff1a;使用配置类连接对应的es服务器创建配置类编写业务逻辑----根据关键字查询相关的聊天内容在ES中插入数据 总结提升 背景 最近需…

如何建设一个安全运营中心(SOC)?

然信息安全管理问题主要是个从上而下的问题&#xff0c;不能指望通过某一种工具来解决&#xff0c;但良好的安全技术基础架构能有效的推动和保障信息安全管理。随着国内行业IT应用度和信息安全管理水平的不断提高&#xff0c;企业对于安全管理的配套设施如安全运营中心&#xf…

51单片机的简易篮球计分器倒计时仿真设计( proteus仿真+程序+原理图+报告+讲解视频)

51单片机的简易篮球计分器倒计时仿真设计( proteus仿真程序原理图报告讲解视频&#xff09; 1.主要功能&#xff1a;2.仿真3. 程序代码4. 原理图5. 设计报告6. 设计资料内容清单&&下载链接 51单片机的简易篮球计分器倒计时仿真设计( proteus仿真程序原理图报告讲解视频…