作者:小傅哥
博客:https://bugstack.cn
沉淀、分享、成长,让自己和他人都能有所收获!??
上学时,老师总说:不会你就问,但多数时候都不知道要问什么!
你总会在小傅哥的文章前言里,发现一些关于成长、学习、感悟以及对当篇内容的一个介绍,其实之所以写这样的铺垫性内容,主要是为了让大家对接下来的内容学习有一个较轻松的开场和过度。
就像我们上学时如果某一科的内容不会时,老师经常会说,你有不会的就要问。但对于学生本身来讲,可能已经不会的太多了,或者压根不知道自己不会什么,只有等看到老师出完的试卷才发现自己什么都不会。但要是让问,又不知道从哪问,问出萝卜带出泥,到处都是知识漏洞。
所以我希望用一些前置内容的铺垫,让大家可以在一个稍有共识的场景下进行学习,或多或少能为你铺垫出一个稍许平缓的接受期。有可能某些时候也会打打鸡血、刺激刺激学习、总归把知识学到手就是好的!
Spring Bean 容器是什么?
Spring 包含并管理应用对象的配置和生命周期,在这个意义上它是一种用于承载对象的容器,你可以配置你的每个 Bean 对象是如何被创建的,这些 Bean 可以创建一个单独的实例或者每次需要时都生成一个新的实例,以及它们是如何相互关联构建和使用的。
如果一个 Bean 对象交给 Spring 容器管理,那么这个 Bean 对象就应该以类似零件的方式被拆解后存放到 Bean 的定义中,这样相当于一种把对象解耦的操作,可以由 Spring 更加容易的管理,就像处理循环依赖等操作。
当一个 Bean 对象被定义存放以后,再由 Spring 统一进行装配,这个过程包括 Bean 的初始化、属性填充等,最终我们就可以完整的使用一个 Bean 实例化后的对象了。
而我们本章节的案例目标就是定义一个简单的 Spring 容器,用于定义、存放和获取 Bean 对象。
凡是可以存放数据的具体数据结构实现,都可以称之为容器。例如:ArrayList、LinkedList、HashSet等,但在 Spring Bean 容器的场景下,我们需要一种可以用于存放和名称索引式的数据结构,所以选择 HashMap 是最合适不过的。
这里简单介绍一下 HashMap,HashMap 是一种基于扰动函数、负载因子、红黑树转换等技术内容,形成的拉链寻址的数据结构,它能让数据更加散列的分布在哈希桶以及碰撞时形成的链表和红黑树上。它的数据结构会尽可能最大限度的让整个数据读取的复杂度在 O(1) ~ O(Logn) ~O(n)之间,当然在极端情况下也会有 O(n) 链表查找数据较多的情况。不过我们经过10万数据的扰动函数再寻址验证测试,数据会均匀的散列在各个哈希桶索引上,所以 HashMap 非常适合用在 Spring Bean 的容器实现上。
另外一个简单的 Spring Bean 容器实现,还需 Bean 的定义、注册、获取三个基本步骤,简化设计如下;
接下来我们就按照这个设计,做一个简单的 Spring Bean 容器代码实现。编码的过程往往并不会有多复杂,但知晓设计过程却更加重要!
small-spring-step-01
└── src
├── main
│ └── java
│ └── cn.bugstack.springframework
│ ├── BeanDefinition.java
│ └── BeanFactory.java
└── test
└── java
└── cn.bugstack.springframework.test
├── bean
│ └── UserService.java
└── ApiTest.java
工程源码:https://github.com/small-spring/small-spring-step-01
Spring Bean 容器类关系,如图 2-2
Spring Bean 容器的整个实现内容非常简单,也仅仅是包括了一个简单的 BeanFactory 和 BeanDefinition,这里的类名称是与 Spring 源码中一致,只不过现在的类实现会相对来说更简化一些,在后续的实现过程中再不断的添加内容。
cn.bugstack.springframework.BeanDefinition
public class BeanDefinition {
private Object bean;
public BeanDefinition(Object bean) {
this.bean = bean;
}
public Object getBean() {
return bean;
}
}
cn.bugstack.springframework.BeanFactory
public class BeanFactory {
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);
}
}
cn.bugstack.springframework.test.bean.UserService
public class UserService {
public void queryUserInfo(){
System.out.println("查询用户信息");
}
}
cn.bugstack.springframework.test.ApiTest
@Test
public void test_BeanFactory(){
// 1.初始化 BeanFactory
BeanFactory beanFactory = new BeanFactory();
// 2.注册 bean
BeanDefinition beanDefinition = new BeanDefinition(new UserService());
beanFactory.registerBeanDefinition("userService", beanDefinition);
// 3.获取 bean
UserService userService = (UserService) beanFactory.getBean("userService");
userService.queryUserInfo();
}
查询用户信息
Process finished with exit code 0
qq空间有欢迎动画,想要给网页制作一个开场动画效果,该怎么制作呢?下面我们就...
前言 现在不管是桌面客户端还是移动客户端,都会夹杂着一部分H5页面,这种混合式...
至上一回分解完淘宝详情页( 点击查看 )后,再写了一篇关于商城基础模板装修首页...
一、反常的SQL语句 某周四午休时分,我正在工位上小憩,睡梦中仿佛看到了自己拿...
企业内部H5微应用开发 分为 服务端API和前端API的开发,主要涉及到进入应用免登...
大家都知道网页中必须要有图片,那么具体的该如何在网页设计中加入图片呢?下面...
CSS 是样式、布局和表示的领域。它充斥着颜色、大小和动画。但是你知道吗,它还...
默认uni-app打包出来的H5在Android上是没法播放.m3u8直播流的,控制台或报错 Unc...
一只小奶狗会有名字、品种以及一堆可爱的特点作为其属性。如果将其建模为一个类...
css-vars-ponyfill 通过css变量来实现网页换肤的过程中,会出现兼容性问题。 为...