手撸Spring:定义一个简单的 Spring 容器(Day1)
一、目标:定义一个简单的 Spring 容器
Spring Bean 容器是什么?
Spring 包含并管理应用对象的配置和生命周期,在这个意义上它是一种用于承载对象的容器,你可以配置你的每个 Bean 对象是如何被创建的,这些 Bean 可以创建一个单独的实例或者每次需要时都生成一个新的实例,以及它们是如何相互关联构建和使用的。
当一个 Bean 对象被定义存放以后,再由 Spring 统一进行装配,这个过程包括 Bean 的初始化、属性填充等,最终我们就可以完整的使用一个 Bean 实例化后的对象了。
二、设计:使用HashMap作为 Spring Bean 容器
一个简单的 Spring Bean 容器实现,还需 Bean 的定义、注册、获取三个基本步骤,简化设计如下;
- 定义:BeanDefinition,可能这是你在查阅 Spring 源码时经常看到的一个类,例如它会包括 singleton、prototype、BeanClassName 等。但目前我们初步实现会更加简单的处理,只定义一个 Object 类型用于存放对象。
- 注册:这个过程就相当于我们把数据存放到 HashMap 中,只不过现在 HashMap 存放的是定义了的 Bean 的对象信息。
- 获取:最后就是获取对象,Bean 的名字就是key,Spring 容器初始化好 Bean 以后,就可以直接获取了。
三、实现
1. 工程结构
1 |
|
Spring Bean 容器类关系,如图 2-2
Spring Bean 容器的整个实现内容非常简单,也仅仅是包括了一个简单的 BeanFactory 和 BeanDefinition,这里的类名称是与 Spring 源码中一致,只不过现在的类实现会相对来说更简化一些,在后续的实现过程中再不断的添加内容。
- BeanDefinition,用于定义 Bean 实例化信息,现在的实现是以一个 Object 存放对象
- BeanFactory,代表了 Bean 对象的工厂,可以存放 Bean 定义到 Map 中以及获取。
2. Bean 定义
cn.chaos.springframework.BeanDefinition
1 |
|
- 目前的 Bean 定义中,只有一个 Object 用于存放 Bean 对象。如果感兴趣可以参考 Spring 源码中这个类的信息,名称都是一样的。
- 不过在后面陆续的实现中会逐步完善 BeanDefinition 相关属性的填充,例如:SCOPE_SINGLETON、SCOPE_PROTOTYPE、ROLE_APPLICATION、ROLE_SUPPORT、ROLE_INFRASTRUCTURE 以及 Bean Class 信息。
3. Bean 工厂
cn.chaos.springframework.BeanFactory
1 |
|
- 在 Bean 工厂的实现中,包括了 Bean 的注册,这里注册的是 Bean 的定义信息。同时在这个类中还包括了获取 Bean 的操作。
- 目前的 BeanFactory 仍然是非常简化的实现,但这种简化的实现内容也是整个 Spring 容器中关于 Bean 使用的最终体现结果,只不过实现过程只展示出基本的核心原理。在后续的补充实现中,这个会不断变得庞大。
四、测试
1. 事先准备
cn.chaos.springframework.test.bean.UserService
1 |
|
- 这里简单定义了一个 UserService 对象,方便我们后续对 Spring 容器测试。
2. 测试用例
cn.chaos.springframework.test.ApiTest
1 |
|
- 在单测中主要包括初始化 Bean 工厂、注册 Bean、获取 Bean,三个步骤,使用效果上贴近与 Spring,但显得会更简化。
- 在 Bean 的注册中,这里是直接把 UserService 实例化后作为入参传递给 BeanDefinition 的,在后续的陆续实现中,我们会把这部分内容放入 Bean 工厂中实现。
3. 测试结果
1 |
|
- 通过测试结果可以看到,目前的 Spring Bean 容器案例,已经稍有雏形。
[文章来源]: https://mp.weixin.qq.com/s?__biz=MzIxMDAwMDAxMw==&mid=2650730551&idx=1&sn=47cfff26ce11cc40c7cdc6495e409c91&chksm=8f6111d5b81698c36470c3413a8343c9e28b0494 “《Spring 手撸专栏》第 2 章:小试牛刀,实现一个简单的Bean容器!”