Spring底层原理(二)
Spring底层原理(二)
BeanFactory的实现
//创建BeanFactory对象
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//注册Bean定义对象
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SpringConfig.class).setScope("singleton").getBeanDefinition();
factory.registerBeanDefinition("config",beanDefinition);
for (String name : factory.getBeanDefinitionNames()) {System.out.println(name);
}
使用AnnotationConfigUtils为容器添加后置处理器
//给BeanFactory添加一些常用的后置处理器,对BeanFactory功能进行增强
AnnotationConfigUtils.registerAnnotationConfigProcessors(factory);
Spring自带的后置处理器
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
-
internalConfigurationAnnotationProcessor:对@Configuration与@Bean注解进行解析处理,为BeanFactory后置处理器 -
internalAutowiredAnnotationProcessor:对@Autowired注解进行解析处理,是Bean后置处理器 -
internalCommonAnnotationProcessor:对@Resource注解进行解析处理,是Bean后置处理器
执行BeanFactory后置处理器
Map<String, BeanFactoryPostProcessor> factoryPostProcessorMap = factory.getBeansOfType(BeanFactoryPostProcessor.class);
for (BeanFactoryPostProcessor processor : factoryPostProcessorMap.values()) {processor.postProcessBeanFactory(factory);
}
- 需要调用这些后置处理器的
postProcessBeanFactory方法,这些处理器才会生效
BeanFactory后置处理器主要功能:补充了一些bean的定义
关联Bean与Bean后置处理器
factory.getBeansOfType(BeanPostProcessor.class).values().forEach(factory::addBeanPostProcessor);
Bean后置处理器:针对Bean的生命周期的各个阶段提供拓展,例如@Autowired @Resource …
💡BeanFactry中的单例对象并不是预先就创建好的,而是第一次从容器中获取时才进行创建

如何将这些单例bean预实例化呢?
factory.preInstantiateSingletons();
- 该方法将所有单例对象进行预实例化

总结
beanFactory不会做的事
- 不会主动调用
BeanFactory后置处理器 - 不会主动添加
Bean后置处理器 - 不会主动初始化单例
- 不会解析
beanFactory,也不会解析${}与#{}
bean后置处理器会有排序的逻辑
-
AnnotationConfigUtils在调用registerAnnotationConfigProcessors方法后,会自动设置一个排序比较器供后续使用
//默认采用list的排序规则 public static void sort(List<?> list) {if (list.size() > 1) {list.sort(INSTANCE);} } -
排序时会调用后置处理器的
getOrder方法,该方法会返回一个整数,根据整数排序-
CommonAnnotationBeanPostProcessorthis.setOrder(2147483644); -
AutowiredAnnotationBeanPostProcessorprivate int order = 2147483645;
所以当
Autowired与Resource注解同时使用时会根据后置处理器的顺序决定谁生效 -
-
测试排序规则
ArrayList<Integer> integers = new ArrayList<>(); integers.add(2147483644); integers.add(2147483645); integers.sort(AnnotationAwareOrderComparator.INSTANCE); //[2147483644, 2147483645]- 数字越小优先级越高,所以
@Resource的优先级更高
- 数字越小优先级越高,所以
ApplicationContext
ClassPathApplicationContext
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="bean1" class="com.vmware.entity.Bean1"/><bean id="bean2" class="com.vmware.entity.Bean2"><property name="bean1" ref="bean1"/></bean>
</beans>
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
String[] names = applicationContext.getBeanDefinitionNames();
for (String name : names) {System.out.println(name);
}
- 较为经典的容器,基于
classpath下的xml格式的配置文件来创建
FileSystemXmlApplicationContext
FileSystemXmlApplicationContext applicationContext=new FileSystemXmlApplicationContext("D:\\spring-simple\\src\\main\\resources\\applicationContext.xml");
String[] names = applicationContext.getBeanDefinitionNames();
for (String name : names) {System.out.println(name);
}
- 基于磁盘路径下
xml格式的配置文件来创建
📖它们是如何将xml配置文件解析完成并加入到beanFactory呢?
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader= new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));
-
在
ClassPathApplicationContext内部会自动创建一个DefaultListableBeanFactory,然后通过XmlBeanDefinitionReader与ClassPathResource对配置文件进行加载并解析,然后将bean加载到容器中 -
FileSystemXmlApplicationContext与ClassPathApplicationContext类似,只是通过FileSystemResource对配置文件进行加载 -
默认情况下使用这两个容器并不会自动引入
spring自带的后置处理器,可以使用标签<context:annotation-config/>进行引入
AnnotationConfigApplicationContext
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
- 基于
java配置类来创建容器 - 会自动注册
spring自带的后置处理器到容器中,同时配置类也会被注册到容器中
AnnotationConfigServletWebServerApplicationContext
AnnotationConfigServletWebServerApplicationContext applicationContext = new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);@Configuration
static class WebConfig{//注册内嵌Web服务器工厂@Beanpublic ServletWebServerFactory servletWebServerFactory(){return new TomcatServletWebServerFactory();}//注册请求分发器@Beanpublic DispatcherServlet dispatcherServlet(){return new DispatcherServlet();}//关联WebServer与DispatcherServlet@Beanpublic DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet){return new DispatcherServletRegistrationBean(dispatcherServlet,"/");}//注册controller,bean的名称如果以/开头,则该名称即为请求路径@Bean("/hello")public Controller controller1(){return (httpServletRequest, httpServletResponse) -> {httpServletResponse.getWriter().write("hello");return null;};}}

- 这是一个经典的容器,基于
java配置类来创建,用于web环境
相关文章:
Spring底层原理(二)
Spring底层原理(二) BeanFactory的实现 //创建BeanFactory对象 DefaultListableBeanFactory factory new DefaultListableBeanFactory(); //注册Bean定义对象 AbstractBeanDefinition beanDefinition BeanDefinitionBuilder.genericBeanDefinition(SpringConfig.class).set…...
springboot188基于spring boot的校园商铺管理系统
项目名称:springboot188基于spring boot的校园商铺管理系统 点击这里进入源码目录 声明: 适用范围: 本文档适用于广泛的学术和教育用途,包括但不限于个人学习、毕业设计和课程设计。免责声明: 特此声明,本…...
【计网 DNS】计算机网络 DNS协议详解:中科大郑烇老师笔记 (六)
目录 0 引言1 DNS概述1.1 定义1.2 DNS域名结构1.2 域名解析步骤 🙋♂️ 作者:海码007📜 专栏:计算机四大基础专栏📜 其他章节:网络快速入门系列、计网概述、计网应用层详解、计网Web和HTTP、计网FTP、计网…...
vue 生命周期钩子函数 mounted()实例
在挂载后操作dom获取焦点。 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"w…...
数据分享 I 地级市人口和土地使用面积基本情况
数据地址: 地级市人口和土地使用面积基本情况https://www.xcitybox.com/datamarketview/#/Productpage?id394 基本信息. 数据名称: 地级市人口和土地使用面积基本情况 数据格式: ShpExcel 数据时间: 2021年 数据几何类型: 面 数据坐标系: WGS84坐标系 数据…...
被邀请为期刊审稿时,如何做一个合格的审稿人?官方版本教程来喽
审稿是学术研究中非常重要的环节,它可以确保研究的科学性和严谨性。审稿人的任务是检查文章是否符合学术规范,是否具有创新性,是否具有科学价值,以及是否符合期刊的定位和风格。因此,审稿人需要具有扎实的学术背景和丰…...
数据飞轮拆解车企数据驱动三板斧:数据分析、市场画像、A/B 实验
更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 近日,火山引擎数智平台(VeDI)2023 数据飞轮汽车行业研讨会在上海举办,活动聚焦汽车行业数字化转型痛点,从…...
基于PyQt5和OpenCV库的简单的文档对齐扫描应用程序
计算机视觉-作业1 作业要求简介说明 安装运行功能使用待完善代码相关 作业要求 拍一张A4纸文稿的图片,利用角点检测、边缘检测等,再通过投影变换完成对文档的对齐扫描 简介 使用python语言,基于PyQt5和OpenCV库的简单的文档对齐扫描应用程…...
【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割2(基础数据流篇)
构建pytorch训练模型读取的数据,是有模版可以参考的,是有套路的,这点相信使用过的人都知道。我也会给出一个套路的模版,方便学习和查询。 同时,也可以先去参考学习之前的一篇较为简单的3D分类任务的数据构建方法,链接在这里:【3D图像分类】基于Pytorch的3D立体图像分类…...
HDR图像处理软件 Photomatix Pro mac中文版新增功能
Photomatix Pro mac是一款专业的HDR合成软件,可以将不同曝光的多张照片合成为一张照片,而保留更多的细节。并且合成时可以帮助去除照片中的鬼影。Photomatix Pro提供两种类型的过程来增加动态范围,一个过程称为HDR色调映射,另一个…...
【Kotlin精简】第5章 简析DSL
1 DSL是什么? Kotlin 是一门对 DSL 友好的语言,它的许多语法特性有助于 DSL 的打造,提升特定场景下代码的可读性和安全性。本文将带你了解 Kotlin DSL 的一般实现步骤,以及如何通过 DslMarker , Context Receivers 等…...
2021年06月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试
Python编程(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 下列程序运行的结果是? s hello print(sworld)A: sworld B: helloworld C: hello D: world 答案:…...
MySQL执行计划分析
执行计划中的常见的列的解释: type system/const :用户主键索引或者唯一索引查询时,只能匹配 1 条数据。一般可以对 sql 查询语句优化成一个常量,那么 type 一般就是 system 或者 const,system 是 const 的一个特例&…...
【数据结构与算法】Snowflake雪花算法Java实现
Snowflake产生的ID由 64 bit 的二进制数字组成,被分成了4个部分,每一部分存储的数据都有特定的含义: 第 0 位: 符号位(标识正负),始终为 0;第 1~41 位 :一共 41 位&…...
重要功能更新:妙手正式接入SHEIN供货模式(OBM)店铺,赋能卖家把握出海新机遇!
继接入SHEIN平台模式店铺之后,妙手ERP积极响应卖家需求,正式接入SHEIN供货模式(OBM)店铺,并支持产品采集、批量刊登、产品管理等功能,帮助跨境卖家快速上品、高效运营,把握出海新机遇。 SHEIN供…...
和鲸ModelWhale与中科可控X系列异构加速服务器完成适配认证,搭载海光芯片,构筑AI算力底座
AIGC 时代,算力作为新型生产力,是国家和企业构建竞争优势的关键。而随着传统计算方式无法满足新时代激增的算力需求,计算场景的多元化和计算应用的复杂化推动了 CPUGPU 异构平台的加速组建。在此全球激烈角逐的大趋势下,我国信创产…...
Vue单文件组件
一、.vue文件 我们使用Vue的单文件组件的时候,一个.vue文件就是一个组件。 例如我们创建一个School组件: 二、组件的结构 我们编写网页代码的时候有HTML结构、CSS样式、JS交互。 组件里也是同样存在这三种结构的: <template><d…...
轻松理解 Transformers(1):Input部分
编者按:Transformers 是人工智能领域近年来最引人瞩目的技术之一,它为语言生成模型的发展做出了巨大的贡献。随着大语言模型(LLM)的兴起,公众对其背后的技术原理也越来越感兴趣。但是由于Transformers本身具有一定的复…...
PHP MySQL 交互 笔记/练习
PHP 与 MySQL 交互 交互函数 函数名作用mysqli_connect()与MySQL 数据库建立连接。mysqli_close()关闭与MYSQL 数据库建立的连接。mysqli_connect_errno()与MySQL 数据库建立连接时,发生错误时的错误编号。mysqli_connect_error()与MySQL 数据库建立连接时&#x…...
领域驱动设计:基于DDD的微服务设计实例
文章目录 项目基本信息战略设计战术设计后续的工作 用一个项目来了解 DDD 的战略设计和战术设计,走一遍从领域建模到微服务设计的全过程,一起掌握 DDD 的主要设计流程和关键 点。 项目基本信息 项目的目标是实现在线请假和考勤管理。功能描述如下&…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
