当前位置: 首页 > 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 的主要设计流程和关键 点。 项目基本信息 项目的目标是实现在线请假和考勤管理。功能描述如下&…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...