手写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.hqwc.cn/news/101566.html

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

相关文章

TDengine 官网换了新“皮肤”,来看看这个风格是不是你的菜

改版升级&#xff0c;不同以“网”&#xff01;为了更好地服务客户&#xff0c;让大家能够更便捷、清晰地了解我们的产品和功能&#xff0c;我们决定给 TDengine 官网换个新“皮肤”~精心筹备下&#xff0c;新官网终于成功与大家见面啦——https://www.taosdata.com/。TDengine…

【开发】安防监控/视频汇聚/云存储/AI智能视频融合平台页面新增地图模式

AI智能分析网关包含有20多种算法&#xff0c;包括人脸、人体、车辆、车牌、行为分析、烟火、入侵、聚集、安全帽、反光衣等等&#xff0c;可应用在安全生产、通用园区、智慧食安、智慧城管、智慧煤矿等场景中。将网关硬件结合我们的视频汇聚/安防监控/视频融合平台EasyCVR一起使…

【业务功能篇92】微服务-springcloud-多线程-异步处理-异步编排-CompletableFutrue

三、CompletableFutrue 一个商品详情页 展示SKU的基本信息 0.5s展示SKU的图片信息 0.6s展示SKU的销售信息 1sspu的销售属性 1s展示规格参数 1.5sspu详情信息 1s 1.ComplatableFuture介绍 Future是Java 5添加的类&#xff0c;用来描述一个异步计算的结果。你可以使用 isDone方…

质量属性案例-架构真题(二十一)

试题一 某电子商务公司升级会员与促销管理系统&#xff0c;向用户提交个性化服务&#xff0c;提高用户粘性。在项目建立之初&#xff0c;公司领导人一致认为目标是提升会员管理方式的灵活性&#xff0c;由于当前用户规模不大&#xff0c;用户简单&#xff0c;系统方面不需要做…

Mac上的视频管理神器:MetaVideo for Mac让你的视频搜索和整理更轻松

视频时代已经来临&#xff0c;我们每天都会接触到各种各样的视频资源。但是&#xff0c;如何管理和编辑这些视频文件&#xff0c;让它们更加易于查找和使用呢&#xff1f;MetaVideo for Mac可以帮助你解决这个问题。 MetaVideo for Mac是一款专门为Mac用户设计的视频管理软件&…

代码随想录算法训练营第五十八天|739. 每日温度、496.下一个更大元素 I

739. 每日温度 文档讲解 &#xff1a; 代码随想录 - 739. 每日温度 状态&#xff1a;再次回顾。 思路&#xff1a; 1. 什么时候用单调栈? 通常是一维数组&#xff0c;要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置&#xff0c;此时就要想到可以用单调栈。…

IDEA版SSM入门到实战(Maven+MyBatis+Spring+SpringMVC) -Maven目录结构和idea的整合

Maven工程目录结构约束(约束>配置>代码) 项目名 src【书写源代码】 main【书写主程序代码】 java【书写java源代码】resources【书写配置文件代码】 test【书写测试代码】 java【书写测试代码】 pom.xml【书写Maven配置】 测试步骤&#xff08;进入项目名根目录【在根…

ElasticSearch第二讲:ES详解 - ElasticSearch基础概念

ElasticSearch第二讲&#xff1a;ES详解 - ElasticSearch基础概念 在学习ElasticSearch之前&#xff0c;先简单了解下ES流行度&#xff0c;使用背景&#xff0c;以及相关概念等。本文是ElasticSearch第二讲&#xff0c;ElasticSearch的基础概念。 文章目录 ElasticSearch第二讲…

北京互联网营销服务商浩希数字科技申请1350万美元纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于北京的互联网营销服务商浩希数字科技&#xff08;Haoxi Health Technology Limited &#xff09;近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯…

【1++的数据结构】之哈希(一)

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的数据结构】 文章目录 一&#xff0c;什么是哈希&#xff1f;二&#xff0c;哈希冲突哈希函数哈希冲突解决 unordered_map与unordered_set 一&#xff0c;什么是哈希&#xff1f; 首先我们要…

重庆旅游攻略

重庆旅游攻略 白天 鹅岭二厂 &#xff08;1&#xff09;地铁线路&#xff1a; 1号线鹅岭站 川美涂鸦一条街 &#xff08;1&#xff09;地铁线路&#xff1a; 黄桷坪正街 湖广会馆 3. 长江索道 需要预约 门票&#xff1a;单程20元&#xff0c;往返30元 4. 重庆动物园 …

selenium 自动化测试——环境搭建

安装python&#xff0c;并且使用pip命令安装 selenium pip3 install selenium 然后尝试第一次使用selenium 完成一个简单的测试自动化脚本 from selenium import webdriver from selenium.webdriver.common.by import By import timedriver webdriver.Chrome() driver.get(…