【框架】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 的常见注解有哪些?

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式Qt 对话框及其类型 QDialog

一.对话框的概念 对话框是与用户进行简短交互的顶层窗口。 QDialog是Qt中所有对话框窗口的基类。 QDialog继承与QWidfet是一种容器类型的组件。 QDialog的意义: QDialog作为一种专业的交互窗口而存在。 QDialog不能作为子部部件嵌入其他容器中。 QDialog是定制…

【算法集训】基础算法:枚举

一、基本理解 枚举的概念就是把满足题目条件的所有情况都列举出来,然后一一判定,找到最优解的过程。 枚举虽然看起来麻烦,但是有时效率上比排序高,也是一个不错的方法、 二、最值问题 1、两个数的最值问题 两个数的最小值&…

力扣刷题:226.反转二叉树

题目: 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:root [2,1,3] 输出:[2…

业务真的需要微服务吗

业务真的需要微服务吗 要说过去十年最火热的软件体系是什么,个人认为莫过于“微服务架构“了。从一线互联网架构师,到刚接触计算机软件不久的学生几乎都或多或少的了解过”微服务“相关知识了,其中在最出名的微服务体系要数 spring cloud 了…

CentOS安装Docker(黑马学习笔记)

Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道。 官方网站上…

作用域、解构、箭头函数

作用域 局部作用域 函数作用域(一直 存在) 块作用域(ES6,只有let和const有块级作用域&#xff0c;var没有) 块就是一对大括号&#xff0c;比如{ }、if(){ }、for(…){ } 使用var则失去块级作用域 //例如 for(var i1;i<3;i) {console.log(i)} console.log(i);//正确&…

Semantic human matting

1.introduction 数据集包括&#xff0c;时尚模特数据集&#xff0c;超过18.8w张模特图&#xff0c;从中选出35311张图片&#xff0c;DIM数据集&#xff0c;仅包含人类的图像&#xff0c;202个前景图像&#xff0c;背景来自coco数据集和互联网&#xff0c;背景图不含人类&#x…

SpringBoot整合MyBatis实现增删改查

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容: SpringBoot整合MyBatis实现增删改查 📚个人知识库: Leo知识库,欢迎大家访…

【问题解决】| 关于torch无法使用GPU的一些实验探索,思考

文章目录 1 研究背景2 问题解决2.1 问题一&#xff0c;这两个版本分别是怎么得到的&#xff1f;2.2 问题二&#xff0c;Windows下安装CUDA Tookit 是必须的吗&#xff1f;2.3 问题三&#xff0c;驱动版本必须大于等于运行时版本吗&#xff1f;2.4 问题四&#xff0c;只运行pip …

【大厂AI课学习笔记NO.56】(9)模型评测

作者简介&#xff1a;giszz&#xff0c;腾讯云人工智能从业者TCA认证&#xff0c;信息系统项目管理师。 博客地址&#xff1a;https://giszz.blog.csdn.net 声明&#xff1a;本学习笔记来自腾讯云人工智能课程&#xff0c;叠加作者查阅的背景资料、延伸阅读信息&#xff0c;及学…

微信小程序证书评级导致接口无法访问问题

微信小程序的ssl证书到期后&#xff0c; 更换了免费的ssl证书&#xff0c; 是在freessl网站申请的&#xff0c; 配置完了&#xff0c;后台可以访问https网页&#xff0c;但是小程序还是无法访问&#xff0c; 开始没有怀疑是https证书的问题&#xff0c; 调适了好长时间的代码&a…

前后端分离vue+nodejs高校体育运动会比赛系统08fv2-python-php-java

实现了一个完整的高校体育运动会比赛系统系统&#xff0c;其中主要有运动项目模块、学生模块、项目类型模块、用户表模块、token表模块、关于我们模块、收藏表模块、公告信息模块、留言板模块、运动论坛模块、配置文件模块、裁判员模块、比赛成绩模块、比赛报名模块、关于我们模…

9、taocms代码审计

一、XSS 1、DOM型xss 限制 无复现 payload: aa)alert(1)( 触发的参数&#xff1a;name代码 根据路由找到对应的文件&#xff0c;在api.php里接受全局变量action&#xff0c;最终赋值给$m,判断 如果$m不在数组就结束&#xff0c;新建方法复制给$model。检查类的方法是否存…

ctf_show笔记篇(web入门---爆破)

爆破 21&#xff1a;直接bp抓包跑字典&#xff0c;需base64加密 22&#xff1a;可用工具跑也可用浏览器找还可以用网上做好的域名查找去找 23&#xff1a;此题需跑脚本已经附上自写脚本 最后跑出来六个答案一个一个尝试得到答案为3j import hashlibm "0123456789qwert…

安卓之ContentProvider的应用场景以及优劣分析

摘要 本文旨在对Android开发中的ContentProvider进行深入探讨。ContentProvider是Android系统中四大组件之一&#xff0c;主要用于在不同的应用程序之间共享数据。本文首先对ContentProvider进行概述&#xff0c;然后分析其应用场景&#xff0c;接着对其优势和劣势进行分析&…

Linux设备模型(十一) - platform设备

一&#xff0c;platform device概述 在Linux2.6以后的设备驱动模型中&#xff0c;需关心总线、设备和驱动这3个实体&#xff0c;总线将设备和驱动绑定。在系统每注册一个设备的时候&#xff0c; 会寻找与之匹配的驱动&#xff1b;相反的&#xff0c;在系统每注册一个设备的时…

开发者38万+,鸿蒙开发岗为何却无人敢应聘?

鸿蒙校园公开课已走进135家高校&#xff0c;305所高校学生参与鸿蒙活动&#xff0c;286家企业参加鸿蒙生态学堂&#xff0c;38万开发者通过鸿蒙认证。 居上华为官方是说有通过鸿蒙开发者认证的已有38万。具体有多少开发者并没有明确表示。除此之外还有200家头部应用加速鸿蒙原…

【Golang切片】

切片 切片的引入内存分析切片的定义切片的遍历切片注意事项 切片的引入 【1】切片&#xff08;slice&#xff09;是golang中一种特有的数据类型 【2】数组有特定的用处&#xff0c;但是却有一些呆板&#xff08;数组长度固定不可变&#xff09;&#xff0c;所以在Go语言的代码…

面试题VUE篇

文章目录 Vue 的核心是什么/请简述你对 vue 的理解请简述 vue 的单向数据流槽口请简述Vue 常用的修饰符有哪些1. 普通修饰符2. 事件修饰符3. 键盘修饰符4. 系统修饰符 v-text 与{{}}与 v-html 区别v-on 可以绑定多个方法吗Vue 循环的 key 作用什么是计算属性Vue 单页面的优缺点…

最新版阿里云Linux CentOS7 ecs-user用户安装Mysql8详细教程(超简单)

经过两天的踩坑后&#xff0c;终于成功安装&#xff0c;并找到了最快捷的安装方式。接下来就由我来给大家介绍不踩坑安装大法&#xff01; 一、下载Mysql 首先前往Mysql官网下载 MySQL官方下载地址 第一步&#xff0c;选择安装包&#xff0c;这是最关键的一步&#xff0c;选错安…