【Spring面试题】

 目录

前言

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

2.什么是AOP?

3.你们项目中有没有使用到AOP?

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

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

6.Spring的bean的生命周期。

7.Spring中的循环引用

8.构造方法出现了循环依赖怎么解决?

9.SpringMVC的执行流程知道嘛?

10.Springboot自动配置原理。

11.Spring 的常见注解有哪些?

12.SpringMVC常见的注解有哪些?

13.Springboot常见注解有哪些?

总结


前言

本文主要介绍了Spring面试题相关的面试题目。


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

不是线程安全的,Spring框架中有一个@Scope注解,默认的值就是singleton,单例的。因为一般在spring的bean中都是注入无状态的对象,没有线程安全问题,如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例或者加锁来解决。

参考回答:不是线程安全的,当多用户同时请求一个服务时,容器会给每一个请求分配一个线程,这时多个线程会并发执行该请求对应的业务逻辑(成员方法),如果该处理逻辑中有对该单列状态的修改(体现为该单例的成员属性),则必须考虑线程同步问题。Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。比如: 我们通常在项目中使用的Spring bean都是不可变的状态(比如Service类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果bean有多种状态的话(比如 View Model对象),就需要自行保证线程安全。最浅显的解决办法就是将多态bean的作用由“singleton”变更为“prototype”。

2.什么是AOP?

面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取公共模块复用,降低耦合。

参考回答:aop是面向切面编程,在spring中用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取公共模块复用,降低耦合,一般可以做为公共日志保存,事务处理等。

3.你们项目中有没有使用到AOP?

记录操作日志,缓存,spring实现的事务。核心:使用aop中的环绕通知+切点表达式(找到要记录日志的方法),通过环绕通知的参数获取请求方法的参数(类、方法、注解、请求方式等),获取到这些参数以后,保存到数据库。

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

其本质是通过AOP功能,对方法前后进行拦截,在执行方法之前开启事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

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

  1. 异常捕获处理,自己处理了异常,没有抛出。    解决:手动抛出。
  2. 抛出检查异常(Spring 默认只会回滚非检查异常)。    解决:配置rollbackFor属性为Exception。
  3. 非public方法导致的事务失效。    解决:改为public。

参考回答:第一个,如果方法上异常捕获处理,自己处理了异常,没有抛出,就会导致事务失效,所以一般处理了异常以后,别忘了抛出去就行了;第二个,如果方法抛出检查异常,如果报错也会导致事务失效,在 spring事务的注解上,就是@Transactional上配置rollbackFor属性为 Exception,这样别管是什么异常,都会回滚事务;第三,如果方法上不是public修饰的,也会导致事务失效。

6.Spring的bean的生命周期。

  1. 通过BeanDefinition获取bean的定义信息
  2. 调用构造函数实例化bean
  3. bean的依赖注入
  4. 处理Aware接口(BeanNameAware、BeanFactoryAware、ApplicationContextAware)
  5. Bean的后置处理器BeanPostProcessor-前置
  6. 初始化方法(InitializingBean、init-method)
  7. Bean的后置处理器BeanPostProcessor-后置
  8. 销毁bean

参考回答:首先会通过一个非常重要的类,叫做BeanDefinition获取bean的定义信息,这里面就封装了bean的所有信息,比如类的全路径、是否是延迟加载、是否是单例等等这些信息在创建bean的时候,第一步是调用构造函数实例化bean;第二步是bean的依赖注入,比如一些set方法注入,像平时开发用的 @Autowire都是这一步完成;第三步是处理Aware接口,如果某一个bean实现了Aware接口就会重写方法执行;第四步是bean的后置处理器BeanPostProcessor,这个是前置处理器;第五步是初始化方法,比如实现了接口InitializingBean或者自定义了方法 init-method标签或@PostContruct;第六步是执行了bean的后置处理器BeanPostProcessor,主要是对bean进行增强,有可能在这里产生代理对象;最后一步是销毁bean。

7.Spring中的循环引用

  • 循环依赖:循环依赖其实就是循环引用,也就是两个或两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于A。
  • 循环依赖在spring中是允许存在,spring框架依据三级缓存已经解决了大部分的循环依赖。
  1. 一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象。
  2. 二级缓存:缓存早期的bean对象(生命周期还没走完)。
  3. 三级缓存:缓存的是ObjectFactory,表示对象工厂,用来创建某个对象。

具体解决流程:

第一,先实例A对象,同时会创建ObjectFactory对象存入三级缓存singletonFactories;第二,A在初始化的时候需要B对象,这个走B的创建的逻辑;第三,B实例化完成,也会创建ObjectFactory对象存入三级缓存singletonFactories  ;第四,B需要注入A,通过三级缓存中获取ObjectFactory来生成一个A的对象,同时存入二级缓存,这个是有两种情况,一个是可能是A的普通对象,另外一个是A的代理对象,都可以让ObjectFactory来生产对应的对象,这也是三 级缓存的关键; 第五,B通过从通过二级缓存earlySingletonObjects获得到A的对象后可以正常注入,B创建成功,存入一级缓存singletonObjects ;第六,回到A对象初始化,因为B对象已经创建完成,则可以直接注入B,A创建成功存入一次缓存singletonObjects;第七,二级缓存中的临时对象A清除。

8.构造方法出现了循环依赖怎么解决?

A依赖于B,B依赖于A,注入的方式是构造函数。

原因:由于bean的生命周期中构造函数是第一个执行的,spring框架并不能解决构造函数的的依赖注入。

解决方案:使用@Lazy进行懒加载,什么时候需要对象再进行bean对象的创建。

参考回答:由于bean的生命周期中构造函数是第一个执行的,spring框架并不能解决构造函数的的依赖注入,可以使用@Lazy懒加载,什么时候需要对象再进行bean对象的创建。

9.SpringMVC的执行流程知道嘛?

视图版本:

  1. 用户发送出请求到前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping(处理器映射器)
  3. HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。
  4. DispatcherServlet调用HandlerAdapter(处理器适配器)
  5. HandlerAdapter经过适配调用具体的处理器(Handler/Controller)
  6. Controller执行完成返回ModelAndView对象
  7. HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet
  8. DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)
  9. ViewReslover解析后返回具体View(视图)
  10. DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)
  11. DispatcherServlet响应用户

前后端开发(接口开发):

  1. 用户发送出请求到前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping(处理器映射器)
  3. HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。
  4. DispatcherServlet调用HandlerAdapter(处理器适配器)
  5. HandlerAdapter经过适配调用具体的处理器(Handler/Controller)
  6. 方法上添加了@ResponseBody
  7. 通过HttpMessageConverter来返回结果转换为JSON并响应

10.Springboot自动配置原理。

在Spring Boot项目中的引导类上有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装,分别是:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

其中@EnableAutoConfiguration是实现自动化配置的核心注解,该注解通过@Import注解导入对应的配置选择器。
内部就是读取了该项目和该项目引用的Jar包的的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。

条件判断会有像@ConditionalOnClass这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的Bean放入spring容器中使用。

11.Spring 的常见注解有哪些?

参考回答:第一类:声明bean,有@Component、@Service、@Repository、@Controller ;第二类:依赖注入相关的,有@Autowired、@Qualifier、@Resourse;第三类:设置作用域 @Scope;第四类:spring配置相关的,比如@Configuration,@ComponentScan 和 @Bean;第五类:跟aop相关做增强的注解 @Aspect,@Before,@After, @Around,@Pointcut。

12.SpringMVC常见的注解有哪些?

参考回答:有@RequestMapping:用于映射请求路径; @RequestBody:注解实现接收http请求的json数据,将json转换为java对 象; @RequestParam:指定请求参数的名称; @PathViriable:从请求路径下中获取请求参数(/user/{id}),传递给方法的 形式参数;@ResponseBody:注解实现将controller方法返回对象转化为json 对象响应给客户端;@RequestHeader:获取指定的请求头数据,还有像 @PostMapping、@GetMapping这些。

13.Springboot常见注解有哪些?

参考回答:Spring Boot的核心注解是@SpringBootApplication ,它由几个注解组成,@SpringBootConfiguration: 组合了@Configuration注解,实现配置文件的功 能; @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项; @ComponentScan:Spring组件扫描。


总结

本文主要介绍了Spring相关的面试题目。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu屏幕小的解决办法

1. 安装vmware tools , 再点自适应客户机 执行里面的vmware-install.pl这个文件 :sudo ./vmware-install.pl 执行不了可以放到家目录,我放在了/home/book 里面 最后点这个自适应客户机 然后我这里点不了是因为我点了控制台视图和拉伸客户机&#xff0c…

交换排序(冒泡排序和快速排序)

交换排序 冒泡排序 传统方法&#xff1a; for (int i 0; i < numsSize - 1; i) {for (int j 0; j < numsSize - 1 - i; j) {if (nums[j] > nums[j 1]) {Swap(&nums[j], &nums[j 1]);}} } 方法二&#xff1a; while循环for循环 int end numsSize - 1…

C++,stl,常用排序算法,常用拷贝和替换算法

目录 1.常用排序算法 sort random_shuffle merge reverse 2.常用拷贝和替换算法 copy replace replace_if swap 1.常用排序算法 sort 默认从小到大排序 #include<bits/stdc.h> using namespace std;int main() {vector<int> v;v.push_back(1);v.push_ba…

使用C++,实现高精度加减乘除法运算!

我的个人主页 {\large \mathsf{{\color{Red} 我的个人主页} } } 我的个人主页 我的专栏&#xff1a; \mathcal{{\color{Green} 我的专栏&#xff1a;} } 我的专栏&#xff1a; 《精选文章》《算法》《每日一道编程题》《高精度算法》 文章目录 前言高精度计算初始模版string 转…

Web APIs -05

js执行机制 js是单线程&#xff0c;同一个时间只能做一件事情&#xff0c;所有任务需要排队所以有时候会渲染不连贯 同步任务 都在主线程上执行&#xff0c;形成一个执行栈 异步任务 js的异步是通过回调函数实现的分为三类&#xff1a;1.普通事件&#xff1a;click等&…

秒懂百科,C++如此简单丨第二十天:贪心算法2

目录 Everyday English 前言 洛谷 P1031 均分纸牌 题目描述 思路点拨 AC代码 洛谷 P1094 纪念品分组 题目描述 样例输入 样例输出 思路点拨 AC代码 洛谷 P2660 zzc 种田 题目描述 思路点拨 AC Code 结尾 Everyday English Dont miss the opportunity. 机不可…

文件管理大师:深入解析Linux的文件与目录操控

目录 一、文件命名规则 1、可以使用哪些字符? 2、文件名的长度 3、Linux文件名大小写 4、Linux文件扩展名 二、文件管理命令 1、目录创建/删除 mkdir创建目录 直接创建文件夹 创建多个文件夹 递归创建写法 总结mkdir 删除空目录 2、文件创建、删除 touch创建文…

【图像分割 2024】ParaTransCNN

【图像分割 2024】ParaTransCNN 论文题目&#xff1a;ParaTransCNN: Parallelized TransCNN Encoder for Medical Image Segmentation 中文题目&#xff1a;用于医学图像分割的并行TransCNN编码器 论文链接&#xff1a;https://arxiv.org/abs/2401.15307 论文代码&#xff1a;H…

UI风格汇:毛玻璃风格风靡的原因解读

Hello&#xff0c;我是大千UI工场&#xff0c;设计风格是我们新开辟的栏目&#xff0c;主要讲解各类UI风格特征、辨识方法、应用场景、运用方法等&#xff0c;本次带来的是毛玻璃风格的解读&#xff0c;有设计需求可以私聊。 一、什么是毛玻璃风格 毛玻璃风格&#xff08;Fros…

(08)Hive——Join连接、谓词下推

前言 Hive-3.1.2版本支持6种join语法。分别是&#xff1a;inner join&#xff08;内连接&#xff09;、left join&#xff08;左连接&#xff09;、right join&#xff08;右连接&#xff09;、full outer join&#xff08;全外连接&#xff09;、left semi join&#xff08;左…

鸿蒙系统优缺点,能否作为开发者选择

凡是都有对立面&#xff0c;就直接说说鸿蒙的优缺点吧。 鸿蒙的缺点&#xff1a; 鸿蒙是从2019年开始做出来的&#xff0c;那时候是套壳Android大家都知晓。从而导致大家不看鸿蒙系统&#xff0c;套壳Android就是多次一举。现在鸿蒙星河版已经是纯血鸿蒙&#xff0c;但是它的…

高性能MySQL 阅读笔记

mysql由服务器端与存储引擎两部分组成&#xff0c;存储引擎部分的锁机制对服务器端是透明的。服务器端内置缓存机制&#xff0c;有解析器和优化器机制。不同的存储引擎对事务、并发等都用不同的处理。 ACID代表的特性&#xff1a;原子性、一致性、隔离性、持久性 共享锁与排他…