当前位置: 首页 > 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
在这里插入图片描述

相关文章:

  • 力扣第87题-扰乱字符串
  • 支持向量机(SVM)在医疗诊断:医学影像领域的应用与实现
  • 现代 JavaScript (ES6+) 入门到实战(八):总结与展望 - 成为一名现代前端开发者
  • 现代 JavaScript (ES6+) 入门到实战(五):告别回调地狱,Promise 完全入门
  • PCB工艺学习与总结-20250628
  • Ubuntu20 编译安装 Redis7.2.4
  • MySQL 安装使用教程
  • Ubuntu22 安装 RTX 5070 Ti Nvidia Driver 驱动
  • NeRF-Lidar实景重建:大疆Mavic 4 Pro低成本建模方案(2025实战指南)
  • docker启动xxl-job 网络问题
  • 解锁Ubuntu安装:从新手到高手的通关秘籍
  • 在Mac上查找并删除Java 21.0.5
  • 阶乘求和全解析:从 Python 秒过到 C++ 手写高精度
  • 【Redis#4】Redis 数据结构 -- String类型
  • 【如何实现分布式压测中间件】
  • 什么是区块哈希(Block Hash)
  • 图片元数据与防篡改技术指南
  • 编写c++程序分别在x86和arm架构的ubuntu下访问CAN 接口设备
  • 80%的知识库场景选择FastGPT,20%的复杂场景选择Dify
  • 设计的“第一性原理”:从Photoshop与Premiere Pro的AI革新谈起