Spring系列面试题(Spring、SpringMvc、SpringBoot)

2023-10-27

一、springboot自动配置原理

自动装配,简单来说就是自动把第三方组件的Bean装载到Spring IOC器里面,不需要开发人员再去写Bean的配置。在Spring Boot应用里面,只需要在启动类加上@SpringBootApplication注解就可以实现自动装配。

原理是:

  • 引入Starter启动依赖组件的时候,这个组件里面必须要包含配置类,在这个配置类里面通过@Bean注解、声明需要装配到IOC容器的Bean对象
  • 配置类是放在第三方的jar包里面,然后通过SpringBoot中的约定优于配置思想,把这个配置类的全路径放在spring.factories文件中。这样SpringBoot就可以知道第三方jar包里面的配置类的位置
  • SpringBoot拿到所第三方jar包里面声明的配置类以后,再通过Spring提供的ImportSelector接口,实现对这些配置类的动态加载

二、springmvc工作流程

  • 1、 用户发送http请求至前端控制器(DispatcherServlet)
  • 2、前端控制器会去遍历所有的处理器映射器(HandlerMapping),寻找一个可以处理该HTTP请求的处理器,生成处理器及处理器拦截器一并返回给前端控制器
  • 3、前端控制前会调用处理器适配器(HandlerAdapter),将请求传递给处理器,处理器调用业务层对数据逻辑进行处理,控制器完成请求处理后,返回ModelAndView对象传给处理器适配器,最终由处理器适配器返回给前端控制器。
  • 4、 前端控制器将ModelAndView传给视图解析器进行渲染视图
  • 5、将处理过后的ModelAndView视图交给前端控制器,并由前端控制器响应给客户端。

具体参考:SpringMVC工作流程 -- 详解_布诺i的博客-CSDN博客_springmvc工作流程

三、描述下spring bean 生命周期

Spring的生命周期被分为五个阶段:

  1. 创建前准备阶段
  2. 创建实例阶段
  3. 依赖注入阶段
  4. 容器缓存阶段
  5. 销毁实例阶段

创建前准备阶段:

这个阶段主要是开始bean加载之前,从spring上下文中去获取相关的配置并且解析,然后找到bean有关的一些配置内容

创建实例阶段:

这个阶段主要是通过反射去创建bean实例对象,并且扫描和解析bean的声明的一些属性.

依赖注入阶段:

这个阶段会监测被实例化的bean是否会存在其他依赖,如果存在其他依赖,就需要将这些依赖注入到bean里面,比如说通过@Autowired等注解去完成依赖注入的配置,

这个阶段又会触发一些扩展的调用,

  • 比如说常见的扩展类BeanPostProcessors,它用来实现bean初始化前后的一个回调;再比如InitializingBean,这个类里面有一个afterPropertiesSet方法,它给属性去赋值.其次还会调用一些后缀Aware接口。
  • 如果 Bean 实现了BeanNameAware 接口,则 Spring调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
  • 如果 Bean 实现了 BeanClassLoaderAware 接口,则 Spring 调用 setBeanClassLoader() 方法传入classLoader的引用。
  • 如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
  • 还有其他一些诸如 EnvironmentAware ,EmbeddedValueResolverAware等接口

容器缓存阶段

这个阶段主要是将bean保存在IOC容器中缓存起来,到了这个阶段,bean就可以去被开发者使用了,那么这个阶段涉及到的操作有,常见的init-method属性配置的方法会在这个阶段被调用

销毁实例阶段

这个阶段是完成spring应用上下文的时候,将去销毁spring上下文中所有bean,如果bean实现了DisposableBean接口的话,或者配置了destory-method属性的方法都将在这个阶段被调用.

四、Spring中的单列bean是线程安全的吗?

​ 在Spring中Bean默认是单列模式,spring框架没有对单列bean进行多线程的封装处理

  1.  无状态就是操作不能保存数据,是线程安全的。
  2.  有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。

解决办法:

  • 改变bean的作用域,把singleton变成prototype 这样相同请求bean相当于new bean(),可以保证线程安全
  • Spring使用ThreadLocal解决线程安全,ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。          

参考:Spring在单例模式下的线程安全_嗨,您好的博客-CSDN博客_spring单例模式怎么保证线程安全

五、Spring事务什么时候会失效

spring事务的原理是aop ,进行了切面的增强,那么失败的根本原因是这个aop不起作用的,常见如下:

  • 发生自调用:类里面使用this调用本类的方法,此时this对象不是代理类,而是userService对象本身
  • 方法不是public  @Transactional只能用于public方法上,否则事务不会生效
  • 数据库不支持事务
  • 没被spring管理 
  • 异常被吃掉,事务不会回滚

 六、Spring的事务传播机制

  • REQUIRED:默认值,支持当前事务,如果没有事务会创建一个新的事务
  • SUPPORTS:支持当前事务,如果没有事务的话以非事务方式执行
  • MANDATORY:支持当前事务,如果没有事务抛出异常
  • REQUIRES_NEW:创建一个新的事务并挂起当前事务
  • NOT_SUPPORTED:以非事务方式执行,如果当前存在事务则将当前事务挂起
  • NEVER:以非事务方式进行,如果存在事务则抛出异常
  • NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与REQUIRED类似的操作

参考:spring事务传播机制_钧令的博客-CSDN博客_spring事务传播机制

七、mybatis里的#{}和${}的区别

#{}是预编译处理,${}是字符串替换。

Mybatis在处理#{}时,会将sql中的#替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理${}时,就是把${}替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。

八、谈谈对ioc的理解

ioc容器实际上是一个map,里面存放是各种对象,在项目启动的时候会读取配置文件里的bean节点,根据限定类名使用反射创建对象放入map里面,这时候map里面有各种对象,接下来我们在代码中使用里面的对象时候,通过依赖注入。

依赖注入是实现ioc的方法,就是在ioc容器运行期间,动态的将某种依赖关系注入到对象中。

控制反转指控制权不是由当前的对象来管理的,由其它类来管理。

九、谈谈对aop的理解

将程序中的交叉业务逻辑(比如日志、事务),封装成一个切面,然后注入到目标对象中,aop可以对某个对象或某个对象的功能进行增强,比如对象中的方法进行增强,可以在执行某个方法之前额外的做一些事情,在某个方法执行之后额外的做一些事情

十、springboot核心注解是什么,它有哪些注解组成

@SpringBootApplication是核心注解 这个注解是整个SpringBoot项目的入口注解,是SpringBoot项目必不可少的注解,它是复合注解,由一下注解组成:

1、@SpringBootConfiguration:SpringBoot的配置类,将此注解标注在某个类上表示这个是一个SpringBoot的配置类。

2、@EnableAutoConfiguration:开启自动配置功能,SpringBoot会帮我们自动配置;

3、@ComponentScan:开启包的扫描功能

十一、springboot中如何解决跨域问题

跨域都是通过前端JSONP来解决,但只能处理get类型请求,像post、put、delete就不支持,所以一般采用后端跨域通过WebMvcConfiguration接口来重写addCorsMappings方法,解决跨域问题。

十二、springboot多环境切换的⽅法


1111是Spring对不同环境提供不同配置功能的⽀持,可以通过激活不同的环境版本,实现快速切换环境;
例如:
application-test.properties 代表测试环境配置
application-dev.properties 代表开发环境配置
但是Springboot并不会直接启动这些配置⽂件,它默认使⽤application.properties主配置⽂件;
我们需要通过⼀个配置来选择需要激活的环境:
spring.profiles.active=dev
spring.profiles.active可以指定配置环境,如指定为dev就会选择 application-dev.properties ⽂件作为配置环境,同理,要指定
不同的环境配置,只需指定application-xxx.properties的xxx即可。
 

十三、说下mybatis的一级缓存和二级缓存

一级缓存是指sqlSession,默认都是开启的,在同一个sqlsession中执行相同的sql,第一次去查询数据库,存在缓存中,第二次直接从缓存中获取,当有insert update delete 操作时,会清空缓存,重新获取

二级缓存是指mapper级别的,默认不开启,如果多个sqlsession之前需要共享内存,则需要使用二级缓存,使用二级缓存属性类,需要实现序列化接口(用来保存对象的状态)

十四、说清楚spring如何解决循环依赖

循环依赖,注意,这里说的是依赖,而不是调用,这是两个概念,一定不要混淆。

循环依赖从字面意思来看,就是A依赖B,然后B依赖A,当然,这个依赖过程也可以更长,不一定就非要两个互相依赖,十个八个也是循环依赖,只要形成了一个闭环。

Spring中的循环依赖包括两种,构造器循环依赖和setter循环依赖。

构造器循环依赖

当使用构造器注入方式时,Spring是无法解决循环依赖的,在出问题时会报错,抛出BeanCurrentlyInCreationException异常。

setter循环依赖

主要来说一下setter循环依赖,通过Spring在创建bean时的一级、二级、三级缓存的概念解决的。

注意:这里解决的只是单例模式下的setter循环依赖,非单例模式下的依然没有办法解决,在业务环境中应当尽量避免此类情况。

创建Bean的缓存概念:

  1. 一级缓存:singletonObjects,可以称为成品池,存放完全实例化属性赋值完成的Bean,直接可以使用。
  2. 二级缓存:earlySingletonObjects,可以称为半成品池,存放早期Bean的引用,尚未属性装配的Bean
  3. 三级缓存:singletonFactories,可以称为工厂池,存放实例化完成的Bean工厂。
  • X1在创建时,首先根据构造函数创建bean,暴露一个Factory给三级缓存(工厂池),并且将其放入二级缓存(半成品池);然后进行属性的装配,发现有依赖关系,查询三级缓存是否存在,如没有,前往创建。
  • 创建X2时,同X1,前往创建X3。
  • 创建X3时,这时三级缓存中已经存在X1,即可直接注入,然后将X3的bean对象放入一级缓存(成品池)。
  • 随后X2、X1依次可以创建完成,并且放入一级缓存中。
  • 如此就完成setter循环依赖问题的解决,核心就是这个三级缓存。

注意:这里的bean对象创建完成,放入一级缓存中时,会将对应的二级、三级缓存清掉。

参考:高频面试题-说清楚Spring如何解决循环依赖? - SegmentFault 思否

十五、springboot、springmvc和spring有什么区别

  • spring 是一个ioc容器、用来管理bean、使用依赖注入实现控制反转、可以很方便整合各种框架、提供aop弥补oop的代码重复问题,方便将不同类相同方法抽取成切面,自动注入给方法执行,比如日志、异常
  • springmvc 是spring对web框架的一个解决方案,提供了前端控制器,用来接收请求,然后定义了一套路由策略(url到handle的映射)及适配执行handle,将handle结果使用视图解析技术生成试图展示给前端
  • springboot 是spring提供的一个快熟开发工具包,让程序员更加方便,更加快速的开发spring+springmvc应用,简化了配置(约定了默认配置)。整合了一系解决方案(starter机制),开箱即用
  • Spring cloud是⼀个基于Spring Boot实现的服务治理框架,⽤于微服务架构中管理和协调各个服务。它提供了一系列组件方便用户快速搭建微服务,如服务发现注册nacos、 配置中⼼nacos、服务网关gateway,客户端负载配置Ribbon、服务间调用openfeign、短路器Hystrix、分布式事务服务Seata等
     

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring系列面试题(Spring、SpringMvc、SpringBoot) 的相关文章

随机推荐

  • 计算机网络原理 谢希仁(第8版)第四章习题答案

    4 01 网络层向上提供的服务有哪两种 试比较其优缺点 面向连接的和无连接 面向连接优点 通过虚电路发送分组 分组只用填写虚电路编号 分组开销较小 分组按序达到终点 面向连接缺点 一个节点出故障 所有通过该节点的虚电路均不能工作 可靠通信交
  • 什么是JavaBean、bean? 什么是POJO、PO、DTO、VO、BO ? 什么是EJB、EntityBean?

    前言 在Java开发中经常遇到这些概念问题 有的可能理解混淆 有的可能理解不到位 特此花了很多时间理顺了这些概念 不过有些概念实际开发中并没有使用到 可能理解还不够准确 只能靠后续不断纠正了 1 什么是POJO POJO Plain Old
  • RPC 技术及其框架 Sekiro 在爬虫逆向中的应用,加密数据一把梭

    文章目录 什么是 RPC JSRPC Sekiro 优缺点 什么是 RPC RPC 英文 RangPaCong 中文让爬虫 旨在为爬虫开路 秒杀一切 让爬虫畅通无阻 开个玩笑 实际上 RPC 为远程过程调用 全称 Remote Proced
  • LeetCode——036

    Valid Sudoku My Submissions QuestionEditorial Solution Total Accepted 71051 Total Submissions 233215 Difficulty Easy Det
  • AI 大行其道,你准备好了吗?—谨送给徘徊于转行 AI 的程序员

    前言 近年来 随着 Google 的 AlphaGo 打败韩国围棋棋手李世乭之后 机器学习尤其是深度学习的热潮席卷了整个 IT 界 所有的互联网公司 尤其是 Google 微软 百度 腾讯等巨头 无不在布局人工智能技术和市场 百度 腾讯 阿
  • 学习Javascript闭包(Closure)[非常棒的文章]

    作者 阮一峰 日期 2009年8月30日 闭包 closure 是Javascript语言的一个难点 也是它的特色 很多高级应用都要依靠闭包实现 下面就是我的学习笔记 对于Javascript初学者应该是很有用的 一 变量的作用域 要理解闭
  • 关于论青少年尽早学少儿编程之说

    关于论青少年尽早学少儿编程之说 正如一本书中所描述的一句话 尽早学习编程 是孩子为未来做好准备必不可少的一步 看完这句话之后 给我们的直观印象可能就是 不教孩子学习编程在某种程度上等于不教他们读书写字 这种说法明显是片面的 编程 读书写字
  • 若依系统注册功能

    加油 三步实现注册 前端 后端 分配角色 总结 前端 login vue中打开注册开关 后端 打开数据库sys config表 开启注册功能 分配角色 在SysUserMapper中添加方法 实现方法 在SysUserServiceImpl
  • dialog中二维码显示问题

    由于dialog加载过程会耗费一定时间 因此在dialog中直接调用会导致在一次打开的dialog无法加载二维码 在dialog标签中加入 opened ShowQRCode 属性 opened是dialog动画打开完毕之后的回调 当页面加
  • 计算机网络层提供的面向连接服务还是无连接服务讨论与思考

    概要 在计算机网络领域 网络层应该向运输层提供怎样的服务 面向连接 还是 无连接 曾引起了长期的争论 争论焦点的实质就是 在计算机通信中 可靠交付应当由谁来负责 是网络还是端系统 介绍 有些人认为应当借助于电信网的成功经验 让网络负责可靠交
  • 计算机主机名与用户名区别

    一 主机名概念 主机名就是计算机的名字 计算机名 网上邻居就是根据主机名来识别的 这个名字可以随时更改 从我的电脑属性的计算机名就可更改 用户登陆时候用的是操作系统的个人用户帐号 这个也可以更改 从控制面板的用户界面里改就可以了 这个用户名
  • 1. Inna and Pink Pony

    1 Inna and Pink Pony 首先找出四个边界点 但要注意当横纵坐标等于边界横纵坐标时 需考虑是否会出界 满足以上条件时 考虑横纵坐标移动次数其和为偶数时便可以完成移动 因为正负抵消原则 话不多说 直接上Python代码 n m
  • 解决 CommandNotFoundError: Your shell has not been properly configured to use ‘conda activate’问题

    针对使用conda进入虚拟环境时遇到的问题 CommandNotFoundError Your shell has not been properly configured to use conda activate 解决方法 win r
  • 解决Android中使用RecyclerView滑动时底部item显示不全的问题

    感觉这个bug是不是因人而异啊 找了很多文章都没能解决我的问题 包括在RecyclerView上在嵌套上一层RelativeLayout 添加属性android descendantFocusability blocksDescendant
  • 解决“L6200E Symbol xx defined (by xx.o and xx.o)”重复定义问题

    今天来分享一个关于自己之前遇到的一个问题 就是关于重复定义会造成的一个错误 错误提示为 OBJ LCD axf Error L6200E Symbol ascii 1206 multiply defined by lcd user o an
  • C语言每日一题:7.寻找数组中心下标。

    思路一 暴力求解 1 定义一个ps作为中间下标去记录下标值 2 循环下标ps从头到位 定义四个变量分别是left sum left right sum right 3 初始化left ps 1和right ps 1 当ps0 gt 就让su
  • etcd学习和实战:4、Java使用etcd实现服务发现和管理

    etcd学习和实战 4 Java使用etcd实现服务发现和管理 文章目录 etcd学习和实战 4 Java使用etcd实现服务发现和管理 1 前言 2 代码 2 1 服务注册 2 2 服务发现 2 3 运行结果 2 4 问题 3 最后 1
  • 关于SVM的一点笔记

    关于SVM的一点笔记 一 简单了解 1 感知机 perceptron 感知机是一种类似于生物中神经细胞功能的人工神经元 它可以把一个或者多个输入 x 1 x 1 x1 x
  • flask最基础的增删改查实现步骤及代码

    分类序列化器 写入要序列化的字段 user info id fields Integer name fields String 商品序列化器 写入要序列化的字段 goods info id fields Integer name field
  • Spring系列面试题(Spring、SpringMvc、SpringBoot)

    一 springboot自动配置原理 自动装配 简单来说就是自动把第三方组件的Bean装载到Spring IOC器里面 不需要开发人员再去写Bean的配置 在Spring Boot应用里面 只需要在启动类加上 SpringBootAppli