当前位置: 首页 > news >正文

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的定义

关联BeanBean后置处理器

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方法,该方法会返回一个整数,根据整数排序

    • CommonAnnotationBeanPostProcessor

      this.setOrder(2147483644);
      
    • AutowiredAnnotationBeanPostProcessor

      private int order = 2147483645;
      

    所以当AutowiredResource注解同时使用时会根据后置处理器的顺序决定谁生效

  • 测试排序规则

    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,然后通过XmlBeanDefinitionReaderClassPathResource对配置文件进行加载并解析,然后将bean加载到容器中

  • FileSystemXmlApplicationContextClassPathApplicationContext类似,只是通过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的校园商铺管理系统

项目名称&#xff1a;springboot188基于spring boot的校园商铺管理系统 点击这里进入源码目录 声明&#xff1a; 适用范围&#xff1a; 本文档适用于广泛的学术和教育用途&#xff0c;包括但不限于个人学习、毕业设计和课程设计。免责声明&#xff1a; 特此声明&#xff0c;本…...

【计网 DNS】计算机网络 DNS协议详解:中科大郑烇老师笔记 (六)

目录 0 引言1 DNS概述1.1 定义1.2 DNS域名结构1.2 域名解析步骤 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;计算机四大基础专栏&#x1f4dc; 其他章节&#xff1a;网络快速入门系列、计网概述、计网应用层详解、计网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 地级市人口和土地使用面积基本情况

数据地址&#xff1a; 地级市人口和土地使用面积基本情况https://www.xcitybox.com/datamarketview/#/Productpage?id394 基本信息. 数据名称: 地级市人口和土地使用面积基本情况 数据格式: ShpExcel 数据时间: 2021年 数据几何类型: 面 数据坐标系: WGS84坐标系 数据…...

被邀请为期刊审稿时,如何做一个合格的审稿人?官方版本教程来喽

审稿是学术研究中非常重要的环节&#xff0c;它可以确保研究的科学性和严谨性。审稿人的任务是检查文章是否符合学术规范&#xff0c;是否具有创新性&#xff0c;是否具有科学价值&#xff0c;以及是否符合期刊的定位和风格。因此&#xff0c;审稿人需要具有扎实的学术背景和丰…...

数据飞轮拆解车企数据驱动三板斧:数据分析、市场画像、A/B 实验

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 近日&#xff0c;火山引擎数智平台&#xff08;VeDI&#xff09;2023 数据飞轮汽车行业研讨会在上海举办&#xff0c;活动聚焦汽车行业数字化转型痛点&#xff0c;从…...

基于PyQt5和OpenCV库的简单的文档对齐扫描应用程序

计算机视觉-作业1 作业要求简介说明 安装运行功能使用待完善代码相关 作业要求 拍一张A4纸文稿的图片&#xff0c;利用角点检测、边缘检测等&#xff0c;再通过投影变换完成对文档的对齐扫描 简介 使用python语言&#xff0c;基于PyQt5和OpenCV库的简单的文档对齐扫描应用程…...

【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割2(基础数据流篇)

构建pytorch训练模型读取的数据,是有模版可以参考的,是有套路的,这点相信使用过的人都知道。我也会给出一个套路的模版,方便学习和查询。 同时,也可以先去参考学习之前的一篇较为简单的3D分类任务的数据构建方法,链接在这里:【3D图像分类】基于Pytorch的3D立体图像分类…...

HDR图像处理软件 Photomatix Pro mac中文版新增功能

Photomatix Pro mac是一款专业的HDR合成软件&#xff0c;可以将不同曝光的多张照片合成为一张照片&#xff0c;而保留更多的细节。并且合成时可以帮助去除照片中的鬼影。Photomatix Pro提供两种类型的过程来增加动态范围&#xff0c;一个过程称为HDR色调映射&#xff0c;另一个…...

【Kotlin精简】第5章 简析DSL

1 DSL是什么&#xff1f; Kotlin 是一门对 DSL 友好的语言&#xff0c;它的许多语法特性有助于 DSL 的打造&#xff0c;提升特定场景下代码的可读性和安全性。本文将带你了解 Kotlin DSL 的一般实现步骤&#xff0c;以及如何通过 DslMarker &#xff0c; Context Receivers 等…...

2021年06月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python编程&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 下列程序运行的结果是&#xff1f; s hello print(sworld)A: sworld B: helloworld C: hello D: world 答案&#xff1a…...

MySQL执行计划分析

执行计划中的常见的列的解释&#xff1a; type system/const &#xff1a;用户主键索引或者唯一索引查询时&#xff0c;只能匹配 1 条数据。一般可以对 sql 查询语句优化成一个常量&#xff0c;那么 type 一般就是 system 或者 const&#xff0c;system 是 const 的一个特例&…...

【数据结构与算法】Snowflake雪花算法Java实现

Snowflake产生的ID由 64 bit 的二进制数字组成&#xff0c;被分成了4个部分&#xff0c;每一部分存储的数据都有特定的含义&#xff1a; 第 0 位&#xff1a; 符号位&#xff08;标识正负&#xff09;&#xff0c;始终为 0&#xff1b;第 1~41 位 &#xff1a;一共 41 位&…...

重要功能更新:妙手正式接入SHEIN供货模式(OBM)店铺,赋能卖家把握出海新机遇!

继接入SHEIN平台模式店铺之后&#xff0c;妙手ERP积极响应卖家需求&#xff0c;正式接入SHEIN供货模式&#xff08;OBM&#xff09;店铺&#xff0c;并支持产品采集、批量刊登、产品管理等功能&#xff0c;帮助跨境卖家快速上品、高效运营&#xff0c;把握出海新机遇。 SHEIN供…...

和鲸ModelWhale与中科可控X系列异构加速服务器完成适配认证,搭载海光芯片,构筑AI算力底座

AIGC 时代&#xff0c;算力作为新型生产力&#xff0c;是国家和企业构建竞争优势的关键。而随着传统计算方式无法满足新时代激增的算力需求&#xff0c;计算场景的多元化和计算应用的复杂化推动了 CPUGPU 异构平台的加速组建。在此全球激烈角逐的大趋势下&#xff0c;我国信创产…...

Vue单文件组件

一、.vue文件 我们使用Vue的单文件组件的时候&#xff0c;一个.vue文件就是一个组件。 例如我们创建一个School组件&#xff1a; 二、组件的结构 我们编写网页代码的时候有HTML结构、CSS样式、JS交互。 组件里也是同样存在这三种结构的&#xff1a; <template><d…...

轻松理解 Transformers(1):Input部分

编者按&#xff1a;Transformers 是人工智能领域近年来最引人瞩目的技术之一&#xff0c;它为语言生成模型的发展做出了巨大的贡献。随着大语言模型&#xff08;LLM&#xff09;的兴起&#xff0c;公众对其背后的技术原理也越来越感兴趣。但是由于Transformers本身具有一定的复…...

PHP MySQL 交互 笔记/练习

PHP 与 MySQL 交互 交互函数 函数名作用mysqli_connect()与MySQL 数据库建立连接。mysqli_close()关闭与MYSQL 数据库建立的连接。mysqli_connect_errno()与MySQL 数据库建立连接时&#xff0c;发生错误时的错误编号。mysqli_connect_error()与MySQL 数据库建立连接时&#x…...

领域驱动设计:基于DDD的微服务设计实例

文章目录 项目基本信息战略设计战术设计后续的工作 用一个项目来了解 DDD 的战略设计和战术设计&#xff0c;走一遍从领域建模到微服务设计的全过程&#xff0c;一起掌握 DDD 的主要设计流程和关键 点。 项目基本信息 项目的目标是实现在线请假和考勤管理。功能描述如下&…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

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期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...