手写简易版Spring IOC容器【学习】

news2024/11/16 2:14:42

这里写自定义目录标题

  • BeanDefinition
    • beanDefinition类
  • 单例对象
    • 单例对象注册(SingletonBeanRegistry)
    • DefaultSingletonBeanRegistry
  • 模板方法 BeanFactory
    • BeanFactory接口
    • AbstractBeanFactory 抽象工厂模板 (getBean)
    • AbstractAutowireCapableBeanFactory (createBean 创建bean)
    • DefaultListableBeanFactory (getBeanDefinition) 获得bean定义

BeanDefinition

beanDefinition类

beanDefinition的作用主要是保存一个对象的类信息.

public class BeanDefinition {
    private Class beanClass;

    public BeanDefinition(Class beanClass){
        this.beanClass = beanClass;
    }

    public Class getBeanClass() {
        return beanClass;
    }

    public void setBeanClass(Class beanClass) {
        this.beanClass = beanClass;
    }
}

单例对象

单例对象注册(SingletonBeanRegistry)

public interface SingletonBeanRegistry {
    Object getSingleton(String beanName);
}

DefaultSingletonBeanRegistry

单例对象保存的具体类,存入到map中,同时拥有get add单例的方法

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {

    private Map<String, Object> singletonObjects = new HashMap<>();

    @Override
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }

    protected void addSingleton(String beanName, Object singletonObject){
        singletonObjects.put(beanName, singletonObject);
    }

}

模板方法 BeanFactory

BeanFactory接口

定义了一个bean工厂拥有的基本方法
其中第一个代表无参生成bean,第二个代表有参生成bean

public interface BeanFactory {

    public Object getBean(String name);

    public Object getBean(String name,Object ...args);

}

AbstractBeanFactory 抽象工厂模板 (getBean)

继承单例 获得单例的全部方法,实现BeanFactory接口
然后定义模板方法和两个抽象方法让子类实现.

public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

    @Override
    public Object getBean(String name) throws BeansException {
        // 首先从单例对象的map中去获取.
        Object bean = getSingleton(name);
        if(bean != null) return bean;
        // 去执行子方法的逻辑获取beanDefinition
        BeanDefinition beanDefinition = getBeanDefinition(name);
        return createBean(name,beanDefinition,null);
    }

    @Override
    public Object getBean(String name, Object... args) {
        // 首先从单例对象的map中去获取.
        Object bean = getSingleton(name);
        if(bean != null) return bean;
        // 去执行子方法的逻辑获取beanDefinition
        BeanDefinition beanDefinition = getBeanDefinition(name);
        return createBean(name,beanDefinition,args);
    }

    protected abstract BeanDefinition getBeanDefinition(String beanName);

    protected abstract Object createBean(String beanName,BeanDefinition beanDefinition,Object[] args) throws BeansException;
}

AbstractAutowireCapableBeanFactory (createBean 创建bean)

继承上一个抽象类实现其中模板定义的一个方法 (createBean)

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {

    private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
        Object bean = null;
        try {
            bean = createBeanInstance(beanDefinition,beanName,args);
        }catch (Exception e){
            e.printStackTrace();
        }
        addSingleton(beanName,bean);
        return bean;
    }

    protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
        Constructor constructorToUse = null;
        Class<?> beanClass = beanDefinition.getBeanClass();
        Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
        for (Constructor ctor : declaredConstructors) {
            if (null != args && ctor.getParameterTypes().length == args.length) {
                constructorToUse = ctor;
                break;
            }
        }
        return instantiationStrategy.instantiate(beanDefinition, beanName, constructorToUse, args);
    }
}

DefaultListableBeanFactory (getBeanDefinition) 获得bean定义

实现模板方法中bean定义的收集.

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {
    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
    @Override
    public BeanDefinition getBeanDefinition(String beanName) {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) throw new RuntimeException("发生了异常");
        return beanDefinition;
    }
    // 注册bean.
    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1935325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

离散数学,汉密尔顿图判定的实际问题,平面图,平面图的判定,欧拉公式,对偶图,五色定理的证明

目录 1.汉密尔顿图判定的实际问题 判断是否是汉密尔顿图 思考&#xff1a;下图中哪些是汉密尔顿图 例子 2.平面图 平面图的基本概念 并非所有的图都能嵌入平面 平面图的面与次数 欧拉公式 欧拉公式的证明 3.平面图的判定 同胚 kuratowski定理 ​4.对偶图 四…

docker 安装并测试(Ubuntu下)

1. 确认安装环境&#xff08;操作系统版本和 CPU 架构&#xff09; 2. 如果有旧版本的 docker 需要进行卸载 使用 docker 命令检查是否已经安装了 docker 如果 docker 已经安装&#xff0c;使用以下命令卸载&#xff1a; apt-get purge docker-ce docker-ce-cli containerd…

​1:1公有云能力整体输出,腾讯云“七剑”下云端

【全球云观察 &#xff5c; 科技热点关注】 曾几何时&#xff0c;云计算技术的兴起&#xff0c;为千行万业的数字化创新带来了诸多新机遇&#xff0c;同时也催生了新产业新业态新模式&#xff0c;激发出高质量发展的科技新动能。很显然&#xff0c;如今的云创新已成为高质量发…

【qt】VS中如何配置Qt环境

https://download.qt.io/official_releases/vsaddin/ 首先需要下载一下vsaddin,上面的是下载的网站. 下载的时候可能会出现下图的情况 说明你下的vsaddin和您的VS版本不匹配,所以你可以多下几个其他版本的vsAddin,一般都是和你VS版本相匹配的才可以,如Vs2022,那就试试vsaddin2…

Alpine Linux 轻量级Linux 适合于 docker 容器镜像

Alpine Linux是创始于2010年4月及以前的、一款开源社区开发的、基于musl libc和BusyBox的轻量级Linux发行版&#xff1b;适合用来做路由器、防火墙、VPNs、VoIP 盒子以及服务器的操作系统。 Alpine 的意思是“高山的”。Alpine Linux 围绕 musl libc 和 busybox 构建。这使得它…

Spring后端框架复习总结

之前写的博客太杂,最近想把后端框架的知识点再系统的过一遍,主要是Spring Boot和Mybatis相关,带着自己的理解使用简短的话把一些问题总结一下,尤其是开发中和面试中的高频问题,基础知识点可以参考之前写java后端专栏,这篇不再赘述。 目录 Spring什么是AOP?底层原理?事务…

[PM]产品运营

生命周期 运营阶段 主要工作 拉新 新用户的定义 冷启动 拉新方式 促活 用户活跃的原因 量化活跃度 运营社区化/内容化 留存 用户流失 培养用户习惯 用户挽回 变现 变现方式 付费模式 广告模式 数据变现 变现指标 传播 营销 认识营销 电商营销中心 拼团活动 1.需求整理 2.…

Linux中安装MySQL

1、新建目录用来存放MySQL安装包&#xff1a; mkdir upload、cd upload 2、输入命令下载MySQL安装包&#xff1a; wget https://cdn.mysql.com/archives/mysql-8.0/mysql-8.0.18-el7-x86_64.tar.gz 3、在系统中安装一系列软件包的&#xff1a; yum -y install wget cmake gcc g…

SonarQube执行代码扫描失败,Can not execute Findbugs

SonarQube 版本 9.2.4 SonarQube执行代码扫描失败&#xff0c;报错如下 remote: INFO: Sensor FindBugs Sensor [findbugs] remote: INFO: Findbugs plugin version: 4.2.6 remote: INFO: JavaResourceLocator.binaryDirs() not available before SonarQube …

【Vue】深入了解 v-for 指令:从基础到高级应用的全面指南

文章目录 一、v-for 指令概述二、v-for 指令的基本用法1. 遍历数组2. 遍历对象3. 使用索引 三、v-for 指令的高级用法1. 组件列表渲染2. 使用 key 提升性能3. 嵌套循环 四、结合其他功能的高级用法1. 处理过滤和排序后的结果2. 迭代数值范围3. 结合其他命令使用模板部分 (<t…

设计模式:使用最广泛的代理模式

需求场景 按着惯例&#xff0c;还是以一个应用场景作为代理模式的切入点。现在有一个订单系统&#xff0c;要求是:一旦订单被创建&#xff0c;只有订单的创建人才可以修改订单中的数据&#xff0c;其他人则不能修改。 基本实现思路 按着最直白的思路&#xff0c;就是查询数据…

数据结构小测试:排序算法

目录 1、请简述数据结构八大排序算法的思路。 2、常用排序算法手写 冒泡排序&#xff1a; 选择排序&#xff1a; 快速排序&#xff1a; 归并排序&#xff1a; 堆排序&#xff1a; 3、额外再加一个二分查找吧 1、请简述数据结构八大排序算法的思路。 冒泡排序&#xff…

golang开发环境搭建与踩坑记录

文章目录 一、安装下载1、go环境2、ide 二、基本使用1、运行2、结构体与方法函数指针3、闭包4、指针5、map6、接口7、异常 三、包管理1、go mod语法2、项目下载所有依赖 一、安装下载 1、go环境 下载地址&#xff1a;https://go.dev/dl/ 或者&#xff1a;https://golang.goog…

19.x86游戏实战-创建MFC动态链接库

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

向量数据库选择浅谈

初见大模型 作为新手接触大模型后&#xff0c;LLM模型、Embedding模型、rank模型、vector模型等等选择上可谓是一步一个坑&#xff0c;迷茫的走在迷茫的大路上。总之各种途径去选择合适的模型&#xff0c;今天了解下向量数据库选择依据。 借鉴前人 学习之前先看看大家都在关注…

基于java+springboot+vue实现的中小企业人事管理系统(文末源码+Lw)128

基于SpringBootVue的实现的中小企业人事管理系统&#xff08;源码数据库万字Lun文流程图ER图结构图ppt演示视频软件包&#xff09; 系统角色&#xff1a; 员工、管理员 系统功能&#xff1a; 管理员登录 进入中小企业人事管理系统可以查看首页、个人中心、员工管理、部门信息管…

arthas监控本地耗时代码(windows)

1、安装 curl -O https://arthas.aliyun.com/arthas-boot.jar 2、运行 java -jar arthas-boot.jar 3、选择监控的程序端口 运行后如下&#xff1a;第二个是我的后端程序&#xff0c;我选择2后回车 4、监控代码块 trace com.example.demo.service.impl.LoginServiceImp…

Docker 镜像使用和安装

​ 1、简介 Docker是一个开源的应用容器引擎&#xff1b;是一个轻量级容器技术&#xff1b; Docker支持将软件编译成一个镜像&#xff1b;然后在镜像中各种软件做好配置&#xff0c;将镜像发布出去&#xff0c;其他使用者可以直接使用这个镜像&#xff1b; 运行中的这个镜像…

Java面试八股之Redis怎么实现消息队列

Redis怎么实现消息队列 Redis实现消息队列主要依赖于其内置的数据结构&#xff0c;如List、Pub/Sub&#xff08;发布/订阅&#xff09;和Stream。下面将分别介绍这三种方式及其特点&#xff1a; 1. List实现消息队列 Redis的List是一个双向链表&#xff0c;支持快速的头部和…

【学术会议征稿】第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)

第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024) 2024 6th International Conference on Frontier Technologies of Information and Computer 第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)将在中国青岛举行&#xff0c;会期是2024年11月8-10日&#xff0c;为…