手写Spring第三篇,原来Spring容器是使用反射来初始化对象的

上次是不是你小子和大家说你拿来做登记的样品被我收了,然后取豆子的时候就是这个样品的?
今天我来辟一下谣,真的是这样的。这小子的样品确实被我收了,不过这小子没给真东西给我,只给了一个指针,害我宝贝得存起来了。结果真东西在我干爹JVM那里。

image.png

这不,今天趁着辟谣。我给大家公布一个好消息,我家工厂马上有生产线了,大家可以多来走走。上次我家工厂被吐槽主要有3个点:

  1. 登记的时候那个死鬼登记员说没样品不行
  2. 登记和取豆子在一个窗口,根本排不过来(虽然没人用)
  3. 没有生产线

今天咱们来一次性解决掉,首先是登记要样品问题,我一个 ctrl-c 一个 ctrl-v 就把这问题解决了。用这个就不用拿样品来了,直接和我说要什么豆子,下次来取我直接给你一个好的豆子。完美!

public class BeanDefinition {  
    private final Class beanClass;  
      
    public BeanDefinition(Class beanClass) {  
        this.beanClass = beanClass;  
    }  
  
    public Class getBeanClass() {  
        return this.beanClass;  
    }  
}

然后是第二个问题,登记和取豆子在一个窗口,根本排不过来。虽然这个问题是我臆想的,但是确实是客观存在的(我到底在说什么?我自己都看不懂了,怎么局里局气的)

image.png

这次取豆子一个窗口,登记一个窗口,再弄一个存豆子的窗口给办事员用。这下你没话说了吧?
我这窗口比豆子都多了。

// 取豆子的窗口
public interface BeanFactory {  
    Object getBean(String name);  
}

// 登记窗口
public interface BeanDefinitionRegistry {  
    void register(String beanName, BeanDefinition beanDefinition);  
}

// 单例豆子窗口,只选优良品种。例如歪瓜和裂枣
public interface SingletonBeanRegistry {
    Object getSingletonBean(String beanName);  
}

再招3个办事员来管3个窗口就O了。

// 单例豆子窗口办事员,这种事情要心腹才行,不然选不到歪瓜裂枣
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {  
  
    Map<String, Object> singletonBeanMap = new HashMap<>();  
  
    @Override  
    public Object getSingletonBean(String beanName) {  
        return singletonBeanMap.get(beanName);  
    }  
  
    protected void register(String beanName, Object bean){  
        singletonBeanMap.put(beanName, bean);  
    }  
}

本来还想再招两个人的,但有个被卷怕的奋斗b来应该说他带一个团队,但只收一个人的工资来干活。我一听这种人肯定有问题,为了试验他,我决定把生产豆子和登记的窗口交给他。毕竟一个团队只给一份工资,打靶老板都是抵挡不住这种诱惑的。

这个奋斗B我叫他模板哥,模板哥以前曾因为老板不让他用模板方法模式愤而离职,后来找不到工作才成了奋斗B,当打靶老板的舔狗。专门带着一个团队干活但只收一份钱。

他说模板这一套他门清,不止写程序要用模板,连带团队抢活干也需要模板,第一步是抢别人工作,第二步是入职还要带团队加班,第三步是让人骂,第四步是让人砍。

image.png

他说这个程序是他见过最契合模板模式的,有人来取豆子的时候执行这几步就行了:

  1. 查一下以前生产过一样的豆子吗?有就直接把豆子给出去
  2. 没有就查一下登记记录,把对应的登记信息拿出来
  3. 拿登记信息去生产豆子,然后把豆子给出去
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {  
    @Override  
    public Object getBean(String name) {  
        Object singletonBean = super.getSingletonBean(name);  
        if (Objects.nonNull(singletonBean)) {  
            return singletonBean;  
        }  
  
        BeanDefinition beanDefinition = getBeanDefinition(name);  
        return createBean(name, beanDefinition);  
    }  
  
    protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeanException;  
  
    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition) throws BeanException;  
}

image.png

团队的二把手我叫他二表弟,不是我的二表弟是模板哥的二表弟。二表弟平时在团队里有表格罩着,经常是干一些别人能看见但又不难的活。这次他就负责生产豆子,然后把豆子放到单例豆子窗口去就完事了。

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {  
    @Override  
    protected Object createBean(String beanName, BeanDefinition beanDefinition) {  
        Object instance;  
        try {  
            instance = beanDefinition.getBeanClass().newInstance();  
        } catch (Exception e) {  
            throw new BeanException("Cannot instantiation a bean: " + beanDefinition.getBeanClass().getName());  
        }  
        super.register(beanName, instance);  
        return instance;  
    }  
}

image.png

团队干活的是大杂烩,他啥都想插一手,啥都想露脸,是模板哥的得力助手。模板哥和大表弟会的他全都会,都是一个团队的,继承一下很正常吧。大杂烩因为能说回道,基本上工厂的事情交给他准没错。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {  
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();  
  
    @Override  
    protected BeanDefinition getBeanDefinition(String beanName) {  
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);  
        if (Objects.isNull(beanDefinition)) {  
            throw new BeanException("Cannot found this bean name: " + beanName); 
        }  
        return beanDefinition;  
    }  
  
    @Override  
    public void register(String beanName, BeanDefinition beanDefinition) {  
        beanDefinitionMap.put(beanName, beanDefinition);  
    }  
}

image.png

团队最后还有一个背锅侠,他平时不干活,出事了就找他。他的口头禅就是:那有什么办法呢?我丢

public class BeanException extends RuntimeException {  
    public BeanException(String message) {  
        super(message);  
    }  
}

我们工厂现在人丁兴旺,得整个关系图才行啊。我怕你们来我工厂的时候认不清人,不知道找谁你就找大杂烩。

image.png

现在来我家工厂就是这样的流程了

public class BeanFactoryTest {  
    @Test  
    public void test() {  
        // 大杂烩把工厂准备好  
        DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();  
  
        // 登记  
        BeanDefinition beanDefinition = new BeanDefinition(SuperMungBean.class);  
        defaultListableBeanFactory.register("superMungBean", beanDefinition);  
  
        // 取豆子  
        SuperMungBean service = (SuperMungBean) defaultListableBeanFactory.getBean("superMungBean");  
  
        // 测试看看豆子好不好吃  
        service.test();  
    }  
}

public class SuperMungBean {  
    public SuperMungBean() {  
    }  
  
    public void test() {  
        System.out.println("超级绿豆那必须好吃啊");  
    }  
}

超级绿豆那必须好吃啊

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Git rebase 的使用(结合图与案例)

目录 Git rebase 的使用Git rebase 概念Git rebase 原理rebase和merge的选择 Git rebase 的使用 在 Git 中整合来自不同分支的修改主要有两种方法&#xff1a;merge 以及 rebase Git rebase 概念 **rebase概念&#xff1a;**用来重新应用提交&#xff08;commits&#xff09…

Llama 3.1 技术研究报告-1

llama3模型 现代⼈⼯智能&#xff08;AI&#xff09;系统由基础模型驱动。本⽂介绍了⼀组新的基础模型&#xff0c;称为Llama 3。它是⼀个语⾔模型群&#xff0c;原⽣⽀持多语⾔性、编码、推理和⼯具使⽤。我们最⼤的模型是⼀个密集变换器&#xff0c;有 405B个参数&#xff0…

oracle 插入date日期类型的数据、插入从表中查出的数据,使用表中的默认数据

date sysdate to_date 插入从表中查出的数据 方式一 方式二 或者指定列名称 下边这个案例的前提是指定列插入&#xff0c;如果不指定&#xff0c;则也是默认的

消息中间件---Kafka

一、什么是Kafka&#xff1f; Kafka是一个分布式流处理平台,类似于消息队列或企业消息传递系统&#xff1b; 流处理事什么呢&#xff1f; 流处理就是数据处理工作流&#xff0c;本质上是一种计算机编程范例。流处理是对接收到的新数据事件的连续处理。‌它涉及对从生产者到消…

HTML+CSS学习笔记

目录 HTML 1.开发环境 2.创建HTML文件 3.HTML元素 3.1HTML文件结构 3.2HTML标签 3.3HTML属性​编辑​编辑 3.4HTML区块 3.4.1块元素 3.4.2行内元素 3.5HTML表单 CSS 1.CSS简介 2.CSS语法​编辑 3.CSS三种导入方式 内联样式 内部样式 外部样式 4.选择器​ 5.C…

9月23日

思维导图 作业 统计家目录下.c文件的个数 #!/bin/bashnum0for file in ~/*.c; doif [ -f "$file" ]; then((num))fi doneecho "家目录下.c文件的个数: $num"

本周宣讲提醒-线上专场——香港科技大学工学院2025/2026年度硕士研究生(MSc)项目招生宣讲会

&#x1f4c6;本周宣讲提醒-线上专场 &#x1f514;香港科技大学工学院2025/2026年度硕士研究生&#xff08;MSc&#xff09;项目招生宣讲会 &#x1f4cd;香港科技大学工学院大挑战研究暨研究生课程信息网络研讨会-线上专场 &#x1f559;时间&#xff1a;2024年9月24日&…

python爬虫中json和xml字符串的xPath和jsonpath过滤语法区别对比

参考博客 两种语法结构作用 为了处理从网络请求返回的网页源码中得到自己想要的数据 首先了解两种库处理的对象语法 jsonpath处理的是json语法格式的字符串 **json&#xff08;JavaScript Object Notation&#xff09;**字符串的语法参考 **类似于下面的格式&#xff0c;以…

【VUE3.0】动手做一套像素风的前端UI组件库---先导篇

系列文章目录 【VUE3.0】动手做一套像素风的前端UI组件库—Button【VUE3.0】动手做一套像素风的前端UI组件库—Radio 目录 系列文章目录引言准备素材字体鼠标手势图 创建vue3项目构建项目1. 根据命令行提示选择如下&#xff1a;2. 进入项目根目录下载依赖并启动。3. 设置项目s…

MySQL函数介绍--日期与时间函数(二)

我相信大家在学习各种语言的时候或多或少听过我们函数或者方法这一类的名词&#xff0c;函数在计算机语言的使用中可以说是贯穿始终&#xff0c;那么大家有没有思考过到底函数是什么&#xff1f;函数的作用又是什么呢&#xff1f;我们为什么要使用函数&#xff1f;其实&#xf…

什么是上层封禁海外流量

上层封禁海外流量&#xff08;Upper-layer Blocking of Overseas Traffic&#xff09;是一种网络安全策略&#xff0c;旨在通过在网络传输的上层进行流量控制和过滤&#xff0c;从而阻止来自海外的恶意流量或不必要的访问。这一措施主要用于防止分布式拒绝服务&#xff08;DDoS…

【AIGC】ChatGPT RAG提取文档内容,高效制作PPT、论文

目录 一、理解 RAG 技术 二、利用 ChatGPT 的 RAG 技术提取文档内容 三、高效制作 PPT 四、高效撰写论文 五、最佳实践与建议 六、工具推荐 随着人工智能生成内容&#xff08;AIGC&#xff09;的快速发展&#xff0c;利用先进的技术工具如 ChatGPT 的 RAG&#xff08;Ret…

【深度学习】(3)--损失函数

文章目录 损失函数一、L1Loss损失函数1. 定义2. 优缺点3. 应用 二、NLLLoss损失函数1. 定义与原理2. 优点与注意3. 应用 三、MSELoss损失函数1. 定义与原理2. 优点与注意3. 应用 四、BCELoss损失函数1. 定义与原理2. 优点与注意3. 应用 五、CrossEntropyLoss损失函数1. 定义与原…

【觅图网-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

Java集合(Map篇)

一.Map a.使用Map i.键值&#xff08;key-value&#xff09;映射表的数据结构&#xff0c;能高效通过key快速查找value&#xff08;元素&#xff09;。 ii.Map是一个接口&#xff0c;最常用的实现类是HashMap。 iii.重复放入k-v不会有问题&#xff0c;但是一个…

Rasa对话模型——做一个语言助手

1、Rasa模型 1.1 模型介绍 Rasa是一个用于构建对话 AI 的开源框架&#xff0c;主要用于开发聊天机器人和语音助手。Rasa 提供了自然语言理解&#xff08;NLU&#xff09;和对话管理&#xff08;DM&#xff09;功能&#xff0c;使开发者能够创建智能、交互式的对话系统。 1.2…

【计算机网络】计算机网络基础二

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; 目录 以太网的通信原理令牌环网的通信原理网络传输基本流程 数据包封装和分用 网络传输流程图 局域网通信&#xff08;同一个网段内的两台…

Java基础笔记1】Java基础语法

目录 一、Java简介 二、JDK和Java初体验 三、配置环境变量 四、IDEA快捷键 五、Java语法基础 1. 注释 2. 字面量 3. 变量 4. 关键字和标识符 5. 变量详解 a. 数值数据在计算机中的存储​编辑 b. 文本、图片、音频等数据在计算机中的存储 c. 八进制和十六进制 6. 数据类型 a. …

Java多线程(1)—线程基础

一、关于线程 1.1 简介 计算机线程&#xff08;Thread&#xff09;是操作系统能够进行运算调度的最小单位。线程的优势在于提高了程序的效率和响应能力&#xff0c;尤其在处理 I/O 操作或多任务时。多线程编程能够充分利用多核处理器的计算能力&#xff0c;达到更高的性能。 …

electron-updater实现electron全量版本更新

在 Electron 应用中使用 electron-updater 来实现自动更新功能时&#xff0c;通常你会在一个专门的模块或文件中管理更新逻辑。如果你想要使用 ES6 的 import 语法来引入 electron-updater&#xff0c;你需要确保你的项目已经配置好了支持 ES6 模块的构建工具&#xff08;如 We…