Spring底层原理

news2024/11/5 4:50:20

BeanFactory和ApplicationContext都可以被称为容器,BeanFactory只负责创建和获取bean

但是ApplicationContext就是调用了BeanFactory的getBean方法。ApplicationContext的getBean方法就是一个门面方法,负责扫描解析配置类,和注册BeanDefinition。功能更全面。就像现实生活中的4S店负责销售,上牌,交税,而bean工厂的就像汽车工厂一样,职责比较单一。

所以单独使用BeanFactroy获取bean是获取不到的。需要自己手动注入BeanDefinition;

在创建容器之前需要先配置bean,可以使用xml的<bean>,也可以使用@Bean,@Component@Import@Configuration等的注解进行配置;将配置的Bean读取成一个BeanDefinition;

一个Bean就会有一个BeanDefinition,所以很多的BeanDefinition也需要有位置存放,所以定义了一个BeanDefinitionMap<key,value>,key就是bean的名字;value就是BeanDefinition。

singletoObjectMap<beanName,bean实例对象>:单例池,所有创建好的单例Bean会存放在单例池中;

所以Spring启动就需要将所有的类都扫描一遍。

  1. BeanFactory生产Bean:工厂生产Bean之前一定要有的BeanDefinition,类似使用说明书。
    1. 生产Bean之前会先判断这个Bean是否已经创建好了;
    2. 如果已经创建好了,会去单例池map中拿取,如果没有创建,就会调用doCreateBean进行实例化。
  2. 实例化:底层就是根据BeanDinfinition中拿到class文件,再通过反射拿到这个Bean机型实例化。Object obj = class.newInstance();//反射的方式获取这个对象,默认通过无参构造函数。没有无参构造函数,就会调用有参构造函数。
    1. spring的三种实例化方式:
      1. 默认通过无参构造函数
      2. 假如没有无参构造函数,会调用有参构造函数,参数通过Spring容器注入到构造函数中。(其实就是再次调用工厂获取参数bean,会先根据类型找,如果找到多个,再根据名字匹配)(期间会产生循环依赖,构造函数的循环依赖加一个@lazy注解可以解决)循环依赖解决方式,依赖注入的方式
      3. 通过XML配置实例化
  3. 属性注入:解析@Autowried,发现有Autowired的属性,就会再次调用工厂的getBean();
  4. 初始化:
    1. 初始化前
    2. 初始化:初始化是确保对象在被使用前处于正确状态的重要步骤。它有助于减少运行时错误,提高代码的可维护性和系统的稳定性。在依赖注入框架中,初始化通常与生命周期回调方法(如@PostConstruct注解的方法)相关联,这些方法在依赖注入完成后被调用,用于执行初始化逻辑。(初始化的init()和构造函数差异,为什么不在构造函数中加载业务逻辑代码,因为有些需要依赖注入的属性还没注入,无法使用,并且如果有多个构造函数,难道业务逻辑要写在多个构造函数中吗?况且在初始化时候已经经过了依赖注入,写业务逻辑代码可以使用,所以我们一个bean如果有写初始化的逻辑可以写在initi()方法然后使用PostConstruct注解)所以Spring专门提供了init()用来初始化方法,方便程序员操作;  
      1. 初始化方式三种:通过init-method的XML配置指定方法,PostConstruct,还可以通过实现InitializingBean接口的afterPropertiesSet()方法初始化
    3. 初始化后:BeanPostProcessor.after()提供给程序员进行扩展的工具;AOP也是在此阶段实现的
      1. Aop底层是通过动态代理实现的;关键方法WarpIfNecessary
      2. JDK动态代理:如果实现了接口,使用JDK动态代理;通过实现的方式加反射的机制。Proxy.class代理类  implement 目标类
      3. CGlib动态代理:如果没实现接口,使用CGlib动态代理:通过继承extends方式,子类调用父类。Proxy.class代理类 extends 目标类
      4. JDK8之前反射更慢,所以CGlib更快;但是JDK8之后差不多
  5. 最后将创建完成的单例bean放入到单例池中;
  6. 销毁;

最终通过ApplicationContext去单例池中拿去一个成熟完整的Bean; 

Bean的作用域为原型的时候,不会放入单例池中,每次都会创建一个新的Bean;

  1. 类(Class):首先,你需要有一个Java类,这个类定义了你想要创建的对象的结构和行为。这个类可以包含属性、方法等,它是你想要实例化的对象的蓝图。

  2. BeanDefinition:然后,你可以定义一个BeanDefinition,这是一个配置元数据,它告诉Spring框架如何创建和管理这个类的实例。BeanDefinition 可以包含类的全限定名、构造函数参数、属性值、初始化方法、销毁方法等信息。

所以,实际上是先有类,然后才有BeanDefinitionBeanDefinition 是基于类的定义来配置的,它描述了如何创建和管理类的实例。没有类,就没有BeanDefinition 可言。​​​​​​​

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

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

相关文章

linux之网络子系统- TCP连接的开销,主要是内存的开销

一、相关实际问题 内核是如何管理内存的如何查看内核使用的内存信息服务器上一条ESTABLISH状态的空连接需要消耗多少内存机器上出现了3万多个TIME_WAIT&#xff0c;内存开销会不会很大 二、Linux内核如何管理内存 内核针对自己的应用场景&#xff0c;使用了一种叫做SLAB/SLU…

企业AI助理驱动的决策支持:从数据洞察到战略执行

在当今瞬息万变的商业环境中&#xff0c;企业面临着前所未有的竞争压力和不确定性。为了保持竞争力&#xff0c;企业不仅需要迅速响应市场变化&#xff0c;还需要做出基于数据的明智决策。随着人工智能技术的飞速发展&#xff0c;企业AI助理正在成为决策过程中的重要工具&#…

二、应用层,《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》

文章目录 零、前言一、应用层协议原理1.1 网络应用的体系结构1.1.1 客户-服务器(C/S)体系结构1.1.2 对等体&#xff08;P2P&#xff09;体系结构1.1.3 C/S 和 P2P体系结构的混合体 1.2 进程通信1.2.1 问题1&#xff1a;对进程进行编址&#xff08;addressing&#xff09;&#…

02-Dubbo特性及工作原理

02-Dubbo特性及工作原理 Dubbo 的特性 这里说一下 Dubbo 最主要的特性&#xff0c;从这些特性中&#xff0c;就可以看出来我们为什么要选用 Dubbo&#xff0c;也可以将 Dubbo 和 Spring Cloud 进行对比&#xff0c;比如我们搭建一套微服务系统&#xff0c;出于什么考虑选用 Dub…

通义灵码AI程序员你在用吗?

大家好&#xff0c;我是袁庭新。之前给大家介绍过AI编码助手——通义灵码&#xff0c;这期给大家分享通义灵码AI程序员的一些功能。 随着大模型的持续进化&#xff0c;在语义理解、代码生成、开发工作流等方面的能力也获得了持续、全面的提升。你说&#xff0c;要是有个编程小…

好难的题啊

序&#xff1a; 1.极坐标本质为变化的圆&#xff1a;动曲线---》格林公式 2.曲线积分常见的化简就是对dx&#xff0c;dy进行操作&#xff0c;这要求寻找到合适函数&#xff0c;而极坐标就是天然的函数&#xff08;参数方程&#xff09; 3.重积分--》累次积分--》单独看其中一…

大学适合学C语言还是Python?

在大学学习编程时&#xff0c;选择C语言还是Python&#xff0c;这主要取决于你的学习目标、专业需求以及个人兴趣。以下是对两种语言的详细比较&#xff0c;帮助你做出更明智的选择&#xff1a; C语言 优点&#xff1a; 底层编程&#xff1a;C语言是一种底层编程语言&#x…

开源模型应用落地-Qwen2.5-7B-Instruct与TGI实现推理加速

一、前言 目前&#xff0c;大语言模型已升级至Qwen2.5版本。无论是语言模型还是多模态模型&#xff0c;均在大规模多语言和多模态数据上进行预训练&#xff0c;并通过高质量数据进行后期微调以贴近人类偏好。在本篇学习中&#xff0c;将集成 Hugging Face的TGI框架实现模型推理…

【QT】Qt对话框

个人主页~ Qt窗口属性~ Qt窗口 五、对话框2、Qt内置对话框&#xff08;1&#xff09;Message Box&#xff08;2&#xff09;QColorDialog&#xff08;3&#xff09;QFileDialog&#xff08;4&#xff09;QFontDialog&#xff08;5&#xff09;QInputDialog 五、对话框 2、Qt内…

ubuntu交叉编译expat库给arm平台使用

1.下载expat库源码: https://github.com/libexpat/libexpat/release?page=2 wget https://github.com/libexpat/libexpat/release/download/R_2_3_0/expat-2.3.0.tar.bz2 下载成功: 2.解压expat库,并进入解压后的目录: tar xjf expat-2.3.0.tar.bz2 cd expat-2.3.0 <…

NPOI 操作详解(操作Excel)

目录 1. 安装 NPOI 2. 使用 NPOI 创建新 Excel 文件 3. 设置列宽和行高 1. 设置列宽 2. 设置行高 3. 同时设置列宽和行高 4. 设置统一的行高 5. 设置统一的列宽 6. 应用统一的行高和列宽 4. 合并单元格 5. 设置单元格样式&#xff08;字体、边框、背景色等&#xf…

【Javaee】网络原理-http协议(二)

前言 上一篇博客初步介绍了抓包工具的安装及使用&#xff0c;介绍了http请求报文与响应报文的格式。​​​​​​【Javaee】网络原理—http协议&#xff08;一&#xff09;-CSDN博客 本篇将详细介绍http的方法和http报文中请求头内部键值对的含义与作用&#xff0c;以及常见状…

大模型系列——AlphaZero/强化学习/MCTS

AlphaGo Zero无需任何人类历史棋谱&#xff0c;仅使用深度强化学习&#xff0c;从零开始训练三天的成就已远远超过了人类数千年积累的围棋知识。 1、围棋知识 &#xff08;1&#xff09;如何简单理解围棋知识 &#xff08;2&#xff09;数子法分胜负&#xff1a;https://zhu…

得物多模态大模型在重复商品识别上的应用和架构演进

重复商品治理介绍 根据得物的平台特性&#xff0c;同一个商品在平台上不能出现多个链接&#xff0c;原因是平台需要保证一品一链的特点&#xff0c;以保障商品的集中竞价&#xff0c;所以说一个商品在整个得物平台上只能有一个商详链接&#xff0c;因此我们需要对一品多链的情…

1、DevEco Studio 鸿蒙仓颉应用创建

1. 仓颉鸿蒙应用简介 因为仓颉是静态编译型语言&#xff0c;使用仓颉开发的应用执行效率更高。而且主打全场景&#xff0c;后续可并入仓颉生态&#xff0c;其和ArkTS都是基于ArkUI进行开发&#xff0c;最大的区别是typescript和仓颉语法间的差异。 2. 应用创建 前置条件&…

vue3项目中实现el-table分批渲染表格

开篇 因最近工作中遇到了无分页情景下页面因大数据量卡顿的问题&#xff0c;在分别考虑并尝试了懒加载、虚拟滚动、分批渲染等各个方法后&#xff0c;最后决定使用分批渲染来解决该问题。 代码实现 表格代码 <el-table :data"currTableData"borderstyle"wi…

LeetCode:82. 删除排序链表中的重复元素 II(重复的一个都不保留)

目录 题目描述: 代码: 第一种: 第二种: 题目描述: 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,3,4,4,5] 输出&#xff1a;[1,2…

偏差与方差的基本概念

在机器学习中&#xff0c;Bias-Variance Tradeoff&#xff08;偏差-方差权衡&#xff09; 是一个核心概念&#xff0c;帮助我们理解模型的误差来源以及如何调节模型复杂度以达到更好的泛化性能。在这篇博客中&#xff0c;我们将深入讨论什么是偏差和方差&#xff0c;以及如何平…

0-ARM Linux驱动开发-字符设备

一、字符设备概述 Linux 系统中&#xff0c;设备被分为字符设备、块设备和网络设备等。字符设备以字节流的方式进行数据传输&#xff0c;数据的访问是按顺序的&#xff0c;一个字节一个字节地进行读取和写入操作&#xff0c;没有缓冲区。例如&#xff0c;终端&#xff08;/dev…

HTML 基础标签——表格标签<table>

文章目录 1. `<table>` 标签:定义表格2. `<tr>` 标签:定义表格行3. `<th>` 标签:定义表头单元格4. `<td>` 标签:定义表格单元格5. `<caption>` 标签:为表格添加标题6. `<thead>` 标签:定义表格头部7. `<tbody>` 标签:定义表格…