深入理解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 测试结果

在这里插入图片描述

成功啦!

相关内容

热门资讯

分享实测“皇后牛牛透视辅助工具... 您好:皇后牛牛这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5951795】很多玩家在皇后牛牛...
玩家必看“微信链接牛牛有透视辅... 您好:微信链接牛牛这款游戏可以开挂,确实是有挂的,需要了解加客服微信【69174242】很多玩家在微...
科技指南“哥哥杭州麻将确实有挂... 亲.哥哥杭州麻将这款游戏是可以开挂的,确实是有挂的,通过添加客服【3671900】很多玩家在这款游戏...
[重磅推荐]天天踢填大坑开挂教... 您好:天天踢填大坑游戏这款游戏可以开挂,确实是有挂的,需要软件加微信【2418389】,很多玩家在天...
{今日重大消息}“小闲54棋牌... 您好:小闲54棋牌这款游戏可以开挂,确实是有挂的,需要了解加客服微信【9307068】很多玩家在这款...