深入理解spring源码 Day01 ( 自己手写一个Bean容器吧!)
创始人
2025-05-30 22:03:44

深入理解spring源码 Day01

  • 1. Spring Bean容器是什么
  • 2. 设计
    • 2.1 Bean的定义
    • 2.2 Bean 工厂
    • 2.3 测试
    • 2.4 测试结果

1. Spring Bean容器是什么

我们先了解一下什么是容器,在Java中凡是可以存放数据的具体数据结构的实现都可以称之为容器。像ArrayList、LinkedList、HashSet等。Spring Bean容器也一样,用来存放Spring框架中最基础的Bean对象。

Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种用于承载对象的容器,你可以配置你的每个Bean对象是如何被创建的,这些Bean可以创建一个单独的实例或者每次都需要生成一个新的实例,以及他们之间是如何关联构建和使用的。

如果一个Bean对象交给Spring容器管理,那么这个Bean对象就应该以类似零件的方式被拆解后存放到Bean的定义中,这样相当于一种把对象解耦的擦操作,可以有Spring更加容易的进行统一的管理,就像处理循环依赖等操作。

当一个Bean对象被定义存放之后,再由Spring统一进行装配,这个过程包括Bean的初始化、属性填充等,最终我们就可以完整的使用一个Bean实例化后的对象了。

2. 设计

因为是我们自己为了更好的了解Spring的实现原理,所以我们由浅入深来实现,这里我们只是先最基础的功能。

在Spring Bean容器场景下,我们需要一种可以存放名称索引式结构,所以毫无疑问,HashMap是最合适不过的。
另外,一个简单的Spring Bean容器是西安,还需要Bean的定义、注册、获取三个基本步骤,简单设计如下:
在这里插入图片描述

  • 定义:BeanDefinition,可能这是我们在看Spring源码时经常看到的一个类,例如它会包括singleton、prototype、BeanClassName等。但是目前我们初步实现会更加简单,只会定义一个Object类型用于存放对象。
  • 注册:这个过程就相当于我们把数据存放到HashMap中,只不过现在HashMap存放的是定义了的Bean的对象信息。
  • 获取:最后就是获取对象,Bean的名字就是key,Spring容器初始化好Bean以后,就可以直接获取了。
    接下来,开干!!!

2.1 Bean的定义

package cn.zrq.springframeowrk;/*** @author zrq* @ClassName BeanDefinition* @date 2023/3/19 21:01* @Description TODO*/
public class BeanDefinition {private Object bean;public BeanDefinition(Object bean) {this.bean = bean;}public Object getBean() {return bean;}public void setBean(Object bean) {this.bean = bean;}
}
  • 目前的 Bean 定义中,只有一个 Object 用于存放 Bean 对象。如果感兴趣可以参考 Spring 源码中这个类的信息,名称都是一样的。

  • 不过在后面陆续的实现中会逐步完善 BeanDefinition 相关属性的填充,例如:SCOPE_SINGLETON、SCOPE_PROTOTYPE、ROLE_APPLICATION、ROLE_SUPPORT、ROLE_INFRASTRUCTURE 以及 Bean Class 信息。

2.2 Bean 工厂

package cn.zrq.springframeowrk;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;/*** @author zrq* @ClassName BeanFactory* @date 2023/3/19 21:02* @Description TODO*/
public class BeanFactory {private Map 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使用的最终体现结果,只不过实现过程只展示出基本的核心原理。在后续的补充实现中,这个会不断变得庞大。

2.3 测试

package cn.zrq.springframeowrk.test;import cn.zrq.springframeowrk.BeanDefinition;
import cn.zrq.springframeowrk.BeanFactory;
import cn.zrq.springframeowrk.service.UserService;/*** @author zrq* @ClassName ApiTest* @date 2023/3/19 21:12* @Description TODO*/
public class ApiTest {//初始化BeanFactoryprivate static BeanFactory beanFactory = new BeanFactory();private static BeanDefinition beanDefinition = new BeanDefinition(new UserService());public static void main(String[] args) {//注册BeanbeanFactory.registerBeanDefinition("userService",beanDefinition);//获取BeanUserService userService = (UserService)beanFactory.getBean("userService");}
}
  • 在测试中主要包括初始化Bean工厂,注册Bean、获取Bean,三个步骤,使用效果上贴近于Spring,但会显得更简化。
  • 在Bean的注册中,这里是直接把UserService实例化后作为参数传递给BeanDefinition的,在后续的视线中,我们会把这部分内容放入Bean工厂中实现。

2.4 测试结果

在这里插入图片描述

成功啦!

相关内容

热门资讯

盘点一款“山水众娱到底有挂吗”... 您好:这款【山水众娱】游戏可以开挂,确实是有挂的,需要软件加微信【1184260】,很多玩家在推筒子...
今日重大通报“湖北家乡麻将究竟... 亲.湖北家乡麻将这款游戏是可以开挂的,确实是有挂的,通过添加客服【4830828】很多玩家在这款游戏...
今日重大通报“微乐陕西三带到底... 您好:微乐陕西三带这款游戏可以开挂,确实是有挂的,需要软件加微信【69174242】,很多玩家在微乐...
今日了解" 成语小秀... 您好:成语小秀才这款游戏是可以开挂的,究竟有没有挂确实能开挂,了解请添加《75638038》(加我们...
分享实测“新乐游到底有挂吗”(... 您好:新乐游这款游戏可以开挂,确实是有挂的,需要软件加微信【5951795】,很多玩家在新乐游这款游...