当前位置: 首页 > news >正文

chapter02_AbstractBeanfactory与模板方法

一、第一个接口BeanFactory

BeanFactory最重要的功能就是提供Bean,给外界使用,所以先新建一个接口BeanFactory

  • 只提供一个获取Bean的方法
public interface BeanFactory {Object getBean(String name);
}

二、定义抽象类AbstractBeanfactory

抽象类AbstractBeanfactory实现BeanFactory接口的思路

  • 引入单例池,作为Bean的缓存
  • 如果这个Bean如果已经存在,则直接从单例池中获取
  • 如果不存在,则应该创建,然后放进单例池,然后返回

创建一个抽象类,使用模板方法设计模式,定义创建Bean这个过程

  • 父类,提供单例池
  • 子类,负责创建Bean
  • 孙子类,管理BeanDefinition
/*** AbstractBeanFactory,模板类,定义了getBean需要的所有方法* @Author 孤风雪影* @Email gitee.com/efairy520* @Date 2025/1/1 0:05* @Version 1.0*/
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {/*** 实现BeanFactory唯一的的getBean方法* @param name* @return*/@Overridepublic Object getBean(String name) {//继承DefaultSingletonBeanRegistry,拥有了单例池管理功能Object bean = getSingleton(name);if (bean != null) {return bean;}//单例池中没有,调用抽象方法BeanDefinition beanDefinition = getBeanDefinition(name);return createBean(name, beanDefinition);}//1. 需要获取BeanDefinition,由孙子类实现protected abstract BeanDefinition getBeanDefinition(String beanName);//2. 创建Bean,由子类实现protected abstract Object createBean(String beanName, BeanDefinition beanDefinition);}

三、抽象类AbstractAutowireCapableBeanFactory

此类仍然是抽象类,本类的任务就是负责创建Bean对象,只需要实现自己负责的那一块任务即可

  • 实现createBean方法
  • 调用doCreateBean的目的,是继续解耦,对外方法名是createBean,对内叫做doCreateBean
package cn.shopifymall.springframework.beans.factory.support;import cn.shopifymall.springframework.beans.factory.config.BeanDefinition;/*** 负责创建Bean** @Author 孤风雪影* @Email gitee.com/efairy520* @Date 2025/1/1 1:01* @Version 1.0*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {/*** 实现父类未实现的createBean方法* @param beanName* @param beanDefinition* @return*/@Overrideprotected Object createBean(String beanName, BeanDefinition beanDefinition) {return doCreateBean(beanName, beanDefinition);}protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) {Class beanClass = beanDefinition.getBeanClass();Object bean = null;try {bean = beanClass.newInstance();} catch (Exception e) {throw new RuntimeException("Instantiation of bean failed", e);}addSingleton(beanName, bean);return bean;}
}

四、普通类DefaultListableBeanFactory

实现了AbstractAutowireCapableBeanFactory,作为真正的BeanFactory

  • 实现了注册Bean定义的功能
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {private final Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {beanDefinitionMap.put(beanName, beanDefinition);}@Overrideprotected BeanDefinition getBeanDefinition(String beanName) {BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (beanDefinition == null) {throw new RuntimeException("No bean named '" + beanName + "' is defined");}return beanDefinition;}
}

五、单例池DefaultSingletonBeanRegistry

这是BeanFactory的顶层类,负责维护Bean单例池

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {private final Map<String, Object> singletonObjects = new HashMap<>();@Overridepublic Object getSingleton(String beanName) {return singletonObjects.get(beanName);}protected void addSingleton(String beanName, Object singletonObject) {singletonObjects.put(beanName, singletonObject);}

六、总结

核心,由AbstractBeanFactory使用模板方法设计模式,拆分BeanFactory为不同的模块

  • DefaultSingletonBeanRegistry,维护Bean单例池
  • AbstractBeanfactory,定义业务流程,串联上下游
  • AbstractAutowireCapableBeanFactory,创建Bean实例
  • DefaultListableBeanFactory(最终类),管理Bean定义
    在这里插入图片描述

测试发现,两次获取的是同一个Bean
在这里插入图片描述

http://www.lryc.cn/news/576834.html

相关文章:

  • python sklearn 机器学习(1)
  • Ragflow本地部署和基于知识库的智能问答测试
  • 【Typst】自定义彩色盒子
  • 医疗AI智能基础设施构建:向量数据库矩阵化建设流程分析
  • 如何搭建基于RK3588的边缘服务器集群?支持12个RK3588云手机
  • Qt QGraphics简述及例程 - QGraphicsView、QGraphicsScene和QGraphicsItem
  • 深入剖析Nacos服务发现与注册,及如何基于LoadBalancer实现负载均衡
  • #华为昇腾#华为计算#昇腾开发者计划2025#
  • Redis分布式锁核心原理源码
  • #华为鲲鹏#华为计算#鲲鹏开发者计划2025#
  • Transformer结构与代码实现详解
  • 【电路笔记 TMS320F28335DSP】TI SCI (增强型的UART) 点对点异步串行通信接口
  • 【OpenGL学习】(八)图形变换
  • Oauth2 自定义设置token过期时间
  • 状态机编程实战 | 如何更优雅地处理字符串
  • 全新大模型开源,腾讯(int4能打DeepSeek) Vs 谷歌(2GB运行多模态)
  • Gemini-CLI:谷歌开源的命令行AI工具,重新定义开发者工作流
  • Ubuntu22 安装 RTX 5070 Ti Nvidia Driver 驱动
  • 自学嵌入式 day27 进程
  • mac系统快捷键及命令安装
  • 状态模式 - Flutter中的状态变身术,让对象随“状态“自由切换行为!
  • 边界的艺术:支持向量机与统计学习时代的王者
  • 设计模式-外观模式、适配器模式
  • 【数据挖掘】聚类算法学习—K-Means
  • YOLOv12_ultralytics-8.3.145_2025_5_27部分代码阅读笔记-conv.py
  • 设备预测性维护和异常检测系统设计方案
  • 【HuggingFace】模型下载至本地访问
  • Git安装全攻略:避坑指南与最佳实践
  • C++ 格式化输入输出
  • 人工智能时代的职业替代风险与应对策略分析