【框架】Spring 框架重点解析

news2024/12/26 23:03:12

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3 + vite 项目可以使用纯Js开发吗?

答案:可以 创建项目: 按照链接参考或者按官方: webstorm 创建vue3 vite 项目-CSDN博客 项目目录 tsconfig.json 配置允许js allowJs指定是否编译js文件,在任意文件当中,如果我们模块使用js写的,那么我们需要 将all…

微软为金融界带来革命性突破——推出Microsoft 365中的下一代AI助手:Microsoft Copilot for Finance

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

【leetcode】相交链表

大家好,我是苏貝,本篇博客带大家刷题,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 点击查看题目 思路: struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *he…

数据分析之Logistic回归分析(二元逻辑回归、多元有序逻辑回归、多元无序逻辑回归)

1、Logistic回归分类 在研究X对于Y的影响时: 如果Y为定量数据,那么使用多元线性回归分析;如果Y为定类数据,那么使用Logistic回归分析。 结合实际情况,可以将Logistic回归分析分为3类: 二元Logistic回归…

今年国内石油需求稳中有升,巡检机器人助力石油行业可持续发展

前言:全球能源市场出现普遍回落趋势,其中石油价格下降近20%,而天然气和煤炭价格更是下跌超过50%。此外,碳酸锂和光伏组件价格也纷纷下降超过50%。这种价格下滑对于全球经济的持续增长,尤其是控制通货膨胀方面&#xff…

CSS 盒子模型(box model)

概念 所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:外边距(margin),边框(border),内边距(pad…

高比例清洁能源接入下计及需求响应的配电网重构(matlab代码)

目录 1 主要内容 目标函数 重要约束条件 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序复现《高比例清洁能源接入下计及需求响应的配电网重构》,以考虑网损成本、弃风弃光成本和开关操作惩罚成本的综合成本最小为目标,针对配电网重构模型的…

mac 本地使用dockerfile启动 springboot项目

1.创建Dockerfile放在项目的根目录下 2.编写Dockerfile FROM openjdk:11 MAINTAINER ChengLinADD target/JiaLi-0.0.1-SNAPSHOT.jar /app.jar# 暴露 Spring Boot 应用的端口号 EXPOSE 8088 # 启动 Spring Boot 应用 CMD ["java", "-jar", "app.jar&q…

1_SQL

文章目录 前端复习SQL数据库的分类关系型数据库非关系型数据库(NoSQL) 数据库的构成软件架构MySQL内部数据组织方式 SQL语言登录数据库数据库操作查看库创建库删除库修改库 数据库中表的操作选择数据库创建表删除表查看表修改表 数据库中数据的操作添加数…

【GPU驱动开发】- AST简介

前言 不必害怕未知,无需恐惧犯错,做一个Creator! AST,抽象语法树,是一种包含丰富语义信息的格式,其中包括类型、表达式树和符号等。 TranslationUnitDecl:该类表示一个输入源文件 ASTContext&…

常见的开源人脸检测模型有哪些

阅读本文之前可以先参阅----神经网络中的重要概念 如何快速入门深度学习 人工智能模型与人脸检测模型详解 一、人工智能模型概述 人工智能(Artificial Intelligence, AI)模型,是指通过计算机算法和数学统计方法,模拟人类智能行为…

C习题003:球筐投球(一排)

题目 输入样例 在这里给出一组输入。例如&#xff1a; 5 3 7 5 7 7 3 1 5 3 1 5 2 4 4 4输出样例 在这里给出相应的输出。例如&#xff1a; 12 10 12 16 8代码长度限制 16 KB 时间限制400 ms 内存限制 64 MB 栈限制 8192 KB 代码 #include<stdio.h> int main() {int…

Netty5 入门HelloWorld

一、客户端代码及关键类说明 /*** netty5的客户端* author -zhengzx-**/ public class ClientSocket {public static void main(String[] args) {//服务类Bootstrap bootstrap new Bootstrap();//workerEventLoopGroup worker new NioEventLoopGroup();try {//设置线程池boo…

javaScript 深浅拷贝

javaScript深浅拷贝 浅拷贝 自己创建一个新的对象&#xff0c;来接受你要重新复制或引用的对象值。如果对象属性是基本的数据类型&#xff0c;复制的就是基本类型的值给新对象&#xff0c;但如果属性是引用数据类型&#xff0c;复制的就是内存中的地址&#xff0c;如果其中一个…

1907_Arm Cortex-M3的基本了解

1907_Arm Cortex-M3的基本了解 全部学习汇总&#xff1a; g_arm_cores: ARM内核的学习笔记 (gitee.com) 我发现Arm Coretex-M3有一个专门的DataSheet&#xff0c;看起来这个的确是被当做了一个设计的产品来对待的。正好&#xff0c;基于这个文件来看看M3具备哪些基本的特性&…

http状态,cookie、session、token的对比

http是无状态的&#xff0c;也就是说断开会话了服务器就不记得任何事情了&#xff0c;但这样对于用户会很麻烦&#xff0c;因为要不停输入用户名和密码 cookie是放在浏览器里的数据&#xff0c;第一次访问后服务器会set cookie&#xff0c;然后浏览器保存这个cookie&#xff0…

Java基于微信小程序的房屋租赁、租房小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

计算机网络_2.1 物理层概述

2.1 物理层概述 一、物理层要实现的功能二、物理层接口特性 B站 深入浅出计算机网络 2.1物理层概述 一、物理层要实现的功能 物理层要实现的功能就是在各种传输媒体上传输比特0和1&#xff0c;进而给上面的数据链路层提供透明传输比特流的服务。 数据链路层“看不见”&#xff…

cpp基础学习笔记03:类型转换

static_cast 静态转换 用于类层次结构中基类和派生类之间指针或者引用的转换。up-casting (把派生类的指针或引用转换成基类的指针或者引用表示)是安全的&#xff1b;down-casting(把基类指针或引用转换成子类的指针或者引用)是不安全的。用于基本数据类型之间的转换&#xff…

微服务day02-Ribbon负载均衡与Nacos安装与入门

一.Ribbon负载均衡 在上一节中&#xff0c;我们通过在RestTemplte实例中加上了注解 LoadBalanced,表示将来由RestTemplate发起的请求会被Ribbon拦截和处理&#xff0c;实现了访问服务时的负载均衡&#xff0c;那么他是如何实现的呢&#xff1f; 1.1 Ribbon负载均衡的原理 Rib…