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

【框架】Spring 框架重点解析

Spring 框架重点解析

1. Spring 框架中的单例 bean 是线程安全的吗?

在这里插入图片描述

不是线程安全的

  • Spring 框架中有一个 @Scope 注解,默认的值是 singleton,即单例的;
  • 因为一般在 Spring 的 bean 对象都是无状态的(在生命周期中不被修改的,比如正经开发下, service 层的和 dao 层的),没有线程安全问题;
  • 如果在 bean 中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例 prototype 或者加锁来解决;

2. 什么是 AOP,你们项目中有没有使用到 AOP 呢?

在这里插入图片描述

什么是 AOP ?

  • 面向切面编程,用户将与业务无直接相关,但却对多个对象产生影响的公共行为和逻辑,将这些抽取成公共模块进行复用,降低耦合度;
  • 可以理解为 一组业务的效果上的"增强buff"

原理就是动态代理

  • 即目标方法的执行时机和结果可以由代理决定和处理;

你们项目有没有使用到 AOP ?

  • 统一处理(拦截器、异常处理器、响应处理器),记录接口访问日志,缓存处理,Spring 实现的事务
  • 记录接口访问日志核心就是,使用 Spring AOP 中的环绕通知 + 切点表达式(找到记录日志的方法),通过环绕通知的参数获取请求方法的参数,获得这些参数后,进行一些业务;

joinPoint.proceed();

代表,切入点执行,也就是目标方法的执行;

3. Spring 中的事务是如何实现的?

对于编程式事务,事务的维护还是有目标方法的业务进行,没用到 AOP,对业务代码入侵性大,项目中很少使用;

而对于声明式事务,通过对方法加注解 @Transactional 声明该方法是一个事务

  • 其本质是通过 AOP 功能,对方法前后进行拦截,在执行方法之前开启事务,在执行完目标方法之后进行提交或者捕获到异常进行回滚事务;

在这里插入图片描述

4. Spring 中事务失效的场景有哪些?

  1. 异常捕获处理,自己业务中处理了异常,没有抛出,这就意味着这个业务被 Spring 认为是“没有问题,无需回滚”
    • 解决:根据实际业务决定是否要手动抛出、手动回滚;
  2. 抛出检查异常(throws),Spring 默认认为事务抛出的检查异常要被调用者处理,故没有回滚;
    • 解决:设置注解 @Transactional 的 rollbackFor 属性为 Exception.class,则即使是检查异常,也会回滚;
  3. 非 public 方法导致的事务失效,由于 Spring 声明式事务的原理是 Spring AOP,所以创建代理、获取参数、添加事务通知,都要求方法是 public;
    • 解决:改为 public;

5. Spring 中 Bean 的生命周期(如何去管理和创建 Bean 实例的?)

在这里插入图片描述

推荐文章:【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)_bean的全局变量-CSDN博客

  1. 通过 BeanDefinition 获取 Bean 的定义信息,调用构造方法创建 Bean(空);

    在这里插入图片描述

  2. Bean 对象中成员变量的依赖注入;

  3. 处理 Aware 接口(Bean Name Aware、Bean Factory Aware、ApplicationContextAware);

  4. Bean 处理器 BeanPostProcessor - 前置;

  5. 初始化方法(InitializingBean、init-method);

  6. Bean 处理器 BeanPostProcessor - 后置;

    • 可以去加强 Bean 对象,例如使其成为代理对象,可以被动态代理;

    在这里插入图片描述

  7. 销毁 Bean;

6. Spring 中的循环引用(循环依赖)

6.1 循环依赖是什么?

在这里插入图片描述

6.2 Spring 的三种缓存

在这里插入图片描述

6.3 一级缓存 + 二级缓存解决普通 Bean 对象的循环依赖

显然,循环依赖的主要原因就是两个对象都是半成品,所以单凭一级缓存是无法解决循环依赖问题的;

在这里插入图片描述

6.4 三种缓存一起解决加强 Bean 对象的循环依赖

由于原始对象是没有被特殊处理的,所以只凭借一二级缓存无法注入一些加强对象,如代理对象;

  • 因为在 6.3 中,将半成品注入给 B,是因为地址后面不会变化,这样即使注入了半成品,也不会影响结果;
  • 而代理对象地址和性质跟原对象是不同的;

这个时候可以加上三级缓存来解决问题;

在这里插入图片描述

6.5 构造方法出现了循环依赖

由于 Bean 的生命周期中构造函数是第一个执行的,Spring 框架并不能解决构造器函数的依赖注入,而我们可以通过“延迟加载”来解决问题;

在这里插入图片描述

6.6 回答

  • 循环依赖:循环依赖也就是循环引用,也就是一个或一个以上的 Bean 互相注入的现象,形成了闭环。如 A 依赖 B,B 依赖 A;
  • 循环依赖在 Spring 中是允许存在的,Spring 框架依据三级缓存已经解决了大部分的循环依赖;
    1. 一级缓存:单例池,存放完整的 Bean 对象;
    2. 二级缓存:缓存 Bean 半成品对象;
    3. 三级缓存:缓存的是 ObjectFactory,表示对象工厂,用来创建某个 Bean(间接存储 Bean 对象);
  • 当然,Spring 无法解决构造方法出现了循环依赖的问题,但是我们可以通过 @Lazy 注解让某个 Bean “延迟加载”来解决问题;

7. Spring MVC 的执行流程知道吗?

7.1 JSP

在这里插入图片描述

7.2 前后端分离

在这里插入图片描述

AOP 也大概在 3、4、5 起代理作用,感兴趣可以去研究,不作为重点;

7.3 回答

Spring MVC 的执行流程是这个框架最核心的内容了,有两种:

  1. 比较老旧的 JSP;
  2. 比较主流的前后端分离的异步、接口开发;

对于 JSP :

  1. 用户发送请求到 前端控制器 DispatcherServlet;
  2. 前端控制器 DispatcherServlet 收到请求调用 处理器映射器 HandlerMapping;
  3. 处理器映射器 HandlerMapping 将 url 映射到对应的处理器,生成 处理器执行链 HandlerExecutionChain 返回给 前端控制器 DispatcherServlet;
  4. 前端控制器 DispatcherServlet 调用 处理器适配器 HandlerAdapter;
  5. 处理器适配器 HandlerAdapter 经过适配调用具体的处理器(Handler/Controller),进行目标方法的参数处理以及返回值处理,并将结果转化为逻辑视图数据 ModelAndView 返回给 前端控制器 DispatcherServlet;
  6. 前端控制器 DispatcherServlet 将 ModelAndView 传给 视图解析器 ViewReslover;
  7. 视图解析器 ViewReslover 将 ModelAndView 解析成真实的视图数据 View 返回给 前端控制器 DispatcherServlet;
  8. 前端控制器 DispatcherServlet 根据 View 进行渲染视图;
  9. 前端控制器 DispatcherServlet 将页面响应给用户;

对于前后端分离:

  1. 用户发送请求到 前端控制器 DispatcherServlet;
  2. 前端控制器 DispatcherServlet 收到请求调用 处理器映射器 HandlerMapping;
  3. 处理器映射器 HandlerMapping 将 url 映射到对应的处理器,生成 处理器执行链 HandlerExecutionChain 返回给 前端控制器 DispatcherServlet;
  4. 前端控制器 DispatcherServlet 调用 处理器适配器 HandlerAdapter;
  5. 处理器适配器 HandlerAdapter 经过适配调用具体的处理器(Handler/Controller),进行目标方法的参数处理以及返回值处理,将数据直接响应给用户;
  6. 方法上如果添加了 @ResponseBody处理器适配器 HandlerAdapter 将目标方法的返回值转化为 JSON 字符串再响应给用户;

8. Spring Boot 自动配置原理

我们知道,Spring 中有不少的 Bean 是自带的和程序员自己写的,那么我们通过启动类,是怎么让这些 Bean 自动配置的呢?

就需要理解一下 Spring Boot 自动配置原理

8.1 @SpringBootApplication 注解

  1. @SpringBootConfiguration:声明一个配置类;
  2. @ComponentScan:组件扫描,扫描的包路径下的 Bean 存到 Spring 容器中;
  3. @EnableAutoConfiguration:Spring Boot 实现自动化配置的核心注解;

在这里插入图片描述

8.2 @EnableAutoConfiguration 注解

  1. @Import 注解导入了配置选择器,读取该项目的以及引用的 jar 包的包路径下的 META-INF/spring.factories 文件中的所有配置类;
  2. 根据一些条件判断的注解去判断是否把配置类中的 Bean 放入 Spring 容器;

在这里插入图片描述

在这里插入图片描述

8.3 回答

在这里插入图片描述

  1. 在 Spring Boot 项目中的引导类有一个注解 @SpringBootApplication,这个注解其实是对三个注解进行了封装,分别是:
    1. @SpringBootConfiguration:声明一个配置类;
    2. @ComponentScan:组件扫描,扫描的包路径下的 Bean 存到 Spring 容器中;
    3. @EnableAutoConfiguration:Spring Boot 实现自动化配置的核心注解;
  2. 其中,核心注解 @EnableAutoConfiguration,通过 @Import 注解导入了配置选择器,读取该项目的以及引用的 jar 包的包路径下的 META-INF/spring.factories 文件中的所有配置类;
  3. 会有一些条件判断的注解(@Conditional 开头),例如:
    1. @ConditionalOnClass 判断是否有对应的字节码文件,如果有字节码,就加载该类把这个配置类所有的 Bean 放入 Spring 容器中;
    2. @ConditionalOnMissingBean 加在 @Bean 标注的方法上,判断是否有对应的 Bean,如果对应的 Bean 不存在,则将这个 Bean 放入 Spring 容器;

9. Spring、Spring Boot、Spring MVC 常见注解有哪些?

9.1 Spring 的常见注解有哪些?

在这里插入图片描述

9.2 Spring MVC 的常见注解有哪些?

在这里插入图片描述

9.3 Spring Boot 的常见注解有哪些?

在这里插入图片描述

相关文章:

【框架】Spring 框架重点解析

Spring 框架重点解析 1. Spring 框架中的单例 bean 是线程安全的吗? 不是线程安全的 Spring 框架中有一个 Scope 注解,默认的值是 singleton,即单例的;因为一般在 Spring 的 bean 对象都是无状态的(在生命周期中不被…...

js中的内存泄漏

理解 内存泄漏是计算机,中由于疏忽或者错误造成程序未能释放已经不在使用的内存,知道浏览器结束 垃圾回收机制 js具有自动的垃圾回收机制,垃圾收集器会定期(周期性)的找出那些不在继续使用的变量,然后释放内存 常见的内存泄漏 意外的全局变量 function foo(){bar 123123…...

营业执照年报申报

姿势:营业执照年报申报 借鉴文章:个体工商户年报申报流程(不要再花冤枉钱) 1、国家企业信用信息公示系统 地址:https://www.gsxt.gov.cn/index.html 2、登录(重庆的方式二简单)...

Springboot教程(五)——单元测试

idea中一般使用JUnit进行单元测试 基本使用 我们可以在idea的test文件夹下的XXXXApplicationTests内进行单元测试: 可以在Test标注的方法上写测试代码: SpringBootTest class C0101ApplicationTests {Testfun contextLoads() {println("Hello …...

【Kotlin】函数

1 常规函数 1.1 无参函数 fun main() {myFun() }fun myFun() {println("myFun") // 打印: myFun } 1.2 有参函数 1)常规调用 fun main() {myFun("myFun") // 打印: myFun }fun myFun(str: String) {println(str) } 2)形参指定默…...

Unity生命周期函数解析

本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com Unity生命周期函数解析 Unity 生命周期函数是在游戏对象的不同阶段被调用的方法,通过这些函数,我们可以在不同的时刻执行特定的代码。在这篇文章中,我们将一步步解析 Unit…...

【Qt】QTextEdit/QPlainTextEdit 实现 Tab 键多行缩进与反缩进

【Qt】QTextEdit/QPlainTextEdit 实现 Tab 键多行缩进与反缩进 文章目录 I - 主要原理II - 代码实现2.1 - 自定义类2.2 - 实现 Tab 缩进2.3 - 实现反缩进 III - 参考链接 I - 主要原理 由于 QTextEdit 和 QPlainTextEdit ,都无法实现多行选中缩进与反缩进&#xff…...

C++缺陷与思考

数组隐式转换为指针 size_t func(int a[10]) {return sizeof(a); }int a[100]; func(a); // 指针大小 sizeof(a); // 数组大小函数的参数看似是一个数组形式,但事实上他已经退化为指针了,也就是等价于size_t func(int* a),而数组作为参数传…...

无公网ip环境使用DS file软件远程访问内网群晖NAS中储存的文件

文章目录 1. 群晖安装Cpolar2. 创建TCP公网地址3. 远程访问群晖文件4. 固定TCP公网地址5. 固定TCP地址连接 DS file 是一个由群晖公司开发的文件管理应用程序,主要用于浏览、访问和管理存储在群晖NAS(网络附加存储)中的文件。这个应用程序具有…...

软件工程基础

本博客地址:https://security.blog.csdn.net/article/details/136446772 一. 软件工程 1、软件危机。具体表现为:软件开发进度难以预测、软件开发成本难以控制、软件功能难以满足用户期望、软件质量无法保证、软件难以维护和软件缺少适当的文档资料。 …...

alzet供应商你值得拥有

在20世纪70年代,ALZE公司研发出来一款巧妙的药物输送装置——Alzet osmotic pump。这款产品如胶囊般精致小巧,它既有胶囊的外表,也具有胶囊的作用。在Alzet osmotic pump中藏有可以装配药物溶液的空间。此款胶囊泵如同一个小投递员&#xff0…...

x86中的TSS与任务切换

前言 今天在学习《深入理解Linux内核》的时候,发现出现了一个新的名词TSS(Task-State Segment),这还是我第一次了解到原来x86提供了硬件级别的任务切换功能,之前以为任务切换都是操作系统实现的来着,这里也…...

打造去中心化透明储蓄罐:Solidity智能合约的又一实践

一、案例背景 传统的储蓄罐通常是由个人或家庭使用,用于存放硬币或小额纸币。然而,这样的储蓄罐缺乏透明性,用户无法实时了解储蓄情况,也无法确保资金的安全性。 通过Solidity智能合约,我们可以构建一个去中心化…...

Java Mybatis数据库面试题

Java Mybatis数据库面试题 前言1、什么是 Mybatis?2、Mybaits 的优缺点:3、SQL 注入如何防止?4、MyBatis 框架适用场合:5、MyBatis 与 Hibernate 有哪些不同?6、#{}和${}的区别是什么?7、当表中的字段名和实…...

LeetCode-第14题-最长公共前缀

1.题目描述 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 2.样例描述 3.思路描述 按字符串数组每个数组的长度,将字符串数组从小到大排序;他们的公共前缀一定小于或等于最长元素长度…...

TCP/UDP模型:2024/2/29

作业1&#xff1a;TCP模型 服务器端&#xff1a; #include <myhead.h> #define SER_IP "192.168.199.129" #define SER_PORT 8899int main(int argc, const char *argv[]) {//1.创建用于连接的套接字文件int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd-1){per…...

微信如何设置自动回复消息,提升沟通效率的?

在日常微信聊天过程中&#xff0c;我们可能会频繁遇到相同问题的客户提问&#xff0c;特别是对于从事销售工作的朋友们而言&#xff0c;客户添加好友后的第一句话常常为“在吗”或“你好”。当我们拥有大量好友&#xff0c;手动逐一回复可能会耗费大量时间。因此&#xff0c;自…...

PCIE的BAR空间

1.PCIe 简介 PCIe&#xff08;Peripheral Component Interconnect Express&#xff09;是一种高速 串行计算机扩展总线标准&#xff0c;主要用于连接主板上的中央处理器&#xff08;CPU&#xff09;和 各种外部设备&#xff0c;如显卡、声卡、硬盘等。PCIe 总线取代了传统的 PC…...

11.互信息-机器学习模型性能的常用的评估指标

互信息&#xff08;Mutual Information&#xff09;是机器学习中常用的一种评估指标&#xff0c;特别是在无监督学习和聚类分析中。它用于衡量两个随机变量之间的相关性或相似性。 定义 给定两个随机变量X和Y&#xff0c;它们的互信息I(X;Y)定义如下&#xff1a; 其中&…...

SpringCloud(18)之Sleuth +Zipkin链路追踪

一、Zipkin介绍 Zipkin是一个开放源代码分布式的跟踪系统&#xff0c;它可以帮助收集服务的时间数据&#xff0c;以解决微服务架构中的延迟问 题&#xff0c;包括数据的收集、存储、查找和展现。每个服务向zipkin报告计时数据&#xff0c;zipkin会根据调用关系通 过Zipkin UI…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)

旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据&#xff01;该数据集源自2025年4月发表于《地理学报》的论文成果…...