Spring常考知识点(IOC、事务、容器等)

2023-09-21 09:59:43


Spring在面试中的 高频问题总结,码起来,面试之前复习一遍!!!

谈谈你对IOC的理解

通常,我们认为Spring有两⼤特性IoC和AOP,那到底该如何理解IoC呢?
对于很多初学者来说,IoC这个概念给⼈的感觉就是我好像会,但是我说不出来
那么IoC到底是什么,接下来来说说我的理解,实际上这是⼀个⾮常⼤的问题,所以我们就把它拆细了来回答,IoC表示控制反转,那么:

  1. 什么是控制?控制了什么?
  2. 什么是反转?反转之前是谁控制的?反转之后是谁控制的?如何控制的?
  3. 为什么要反转?反转之前有什么问题?反转之后有什么好处?

这就是解决这⼀类⼤问题的思路,⼤⽽化⼩。
那么,我们先来解决第⼀个问题:什么是控制?控制了什么?
我们在⽤Spring的时候,我们需要做什么:

  1. 建⼀些类,⽐如UserService、OrderService
  2. ⽤⼀些注解,⽐如@Autowired

但是,我们也知道,当程序运⾏时,⽤的是具体的UserService对象、OrderService对象,那这些对象是什么时候创建的?谁创建的?包括对象⾥的属性是什么时候赋的值?谁赋的?所有这些都是我们程序员做的,以为我们只是写了类⽽已,所有的这些都是Spring做的,它才是幕后⿊⼿。
这就是控制:

  1. 控制对象的创建
  2. 控制对象内属性的赋值

如果我们不⽤Spring,那我们得⾃⼰来做这两件事,反过来,我们⽤Spring,这两件事情就不⽤我们做了,我们要做的仅仅是定义类,以及定义哪些属性需要Spring来赋值(⽐如某个属性上加@Autowired),⽽这其实就是第⼆个问题的答案,这就是反转,表示⼀种对象控制权的转移。
那反转有什么⽤,为什么要反转?
如果我们⾃⼰来负责创建对象,⾃⼰来给对象中的属性赋值,会出现什么情况?
⽐如,现在有三个类:

  1. A类,A类⾥有⼀个属性C c;
  2. B类,B类⾥也有⼀个属性C c;
  3. C类

现在程序要运⾏,这三个类的对象都需要创建出来,并且相应的属性都需要有值,那么除开定义这三个
类之外,我们还得写:

  1. A a = new A();
  2. B b = new B();
  3. C c = new C();
  4. a.c = c;
  5. b.c = c;

这五⾏代码是不⽤Spring的情况下多出来的代码,⽽且,如果类在多⼀些,类中的属性在多⼀些,那相应的代码会更多,⽽且代码会更复杂。所以我们可以发现,我们⾃⼰来控制⽐交给Spring来控制,我们的代码量以及代码复杂度是要⾼很多的,反⾔之,将对象交给Spring来控制,减轻了程序员的负担。
总结⼀下,IoC表示控制反转,表示如果⽤Spring,那么Spring会负责来创建对象,以及给对象内的属性赋值,也就是如果⽤Spring,那么对象的控制权会转交给Spring。
以上是SpringIOC的理解,参考这两篇文章可以更好地理解IOC原理:
IOC概述及其实现原理
理解Spring原理 - 手写IOC和DI

单例Bean和单例模式

单例模式表示JVM中某个类的对象只会存在唯⼀⼀个。
⽽单例Bean并不表示JVM中只能存在唯⼀的某个类的Bean对象。

Spring事务传播机制

多个事务⽅法相互调⽤时,事务如何在这些⽅法间传播,⽅法A是⼀个事务的⽅法,⽅法A执⾏过程中调⽤了⽅法B,那么⽅法B有⽆事务以及⽅法B对事务的要求不同都会对⽅法A的事务具体执⾏造成影响,同时⽅法A的事务对⽅法B的事务执⾏也有影响,这种影响具体是什么就由两个⽅法所定义的事务传播类型所决定。

  1. REQUIRED(Spring默认的事务传播类型):如果当前没有事务,则⾃⼰新建⼀个事务,如果当前存 在事务,则加⼊这个事务
  2. SUPPORTS:当前存在事务,则加⼊当前事务,如果当前没有事务,就以⾮事务⽅法执⾏
  3. MANDATORY:当前存在事务,则加⼊当前事务,如果当前事务不存在,则抛出异常。
  4. REQUIRES_NEW:创建⼀个新事务,如果存在当前事务,则挂起该事务。
  5. NOT_SUPPORTED:以⾮事务⽅式执⾏,如果当前存在事务,则挂起当前事务
  6. NEVER:不使⽤事务,如果当前事务存在,则抛出异常
  7. NESTED:如果当前事务存在,则在嵌套事务中执⾏,否则REQUIRED的操作⼀样(开启⼀个事
    务)

Spring事务什么时候会失效

spring事务的原理是AOP,进⾏了切⾯增强,那么失效的根本原因是这个AOP不起作⽤了!常⻅情况有如下⼏种

  1. 发⽣⾃调⽤,类⾥⾯使⽤this调⽤本类的⽅法(this通常省略),此时这个this对象不是代理类,⽽是UserService对象本身!解决⽅法很简单,让那个this变成UserService的代理类即可!
  2. ⽅法不是public的:@Transactional 只能⽤于 public 的⽅法上,否则事务不会失效,如果要⽤在⾮ public ⽅法上,可以开启 AspectJ 代理模式。
  3. 数据库不⽀持事务
  4. 没有被spring管理
  5. 异常被吃掉,事务不会回滚(或者抛出的异常没有被定义,默认为RuntimeException)

Spring中的Bean创建的⽣命周期有哪些步骤

Spring中⼀个Bean的创建⼤概分为以下⼏个步骤:

  1. 推断构造⽅法
  2. 实例化
  3. 填充属性,也就是依赖注⼊
  4. 处理Aware回调
  5. 初始化前,处理@PostConstruct注解
  6. 初始化,处理InitializingBean接⼝
  7. 初始化后,进⾏AOP

Spring中Bean是线程安全的吗

Spring本身并没有针对Bean做线程安全的处理,所以:

  1. 如果Bean是⽆状态的,那么Bean则是线程安全的
  2. 如果Bean是有状态的,那么Bean则不是线程安全的

另外,Bean是不是线程安全,跟Bean的作⽤域没有关系,Bean的作⽤域只是表示Bean的⽣命周期范围,对于任何⽣命周期的Bean都是⼀个对象,这个对象是不是线程安全的,还是得看这个Bean对象本身。

ApplicationContext和BeanFactory有什么区别

BeanFactory是Spring中⾮常核⼼的组件,表示Bean⼯⼚,可以⽣成Bean,维护Bean,⽽ApplicationContext继承了BeanFactory,所以ApplicationContext拥有BeanFactory所有的特点,也是⼀个Bean⼯⼚,但是ApplicationContext除开继承了BeanFactory之外,还继承了诸如EnvironmentCapableMessageSourceApplicationEventPublisher等接⼝,从⽽ApplicationContext还有获取系统环境变量、国际化、事件发布等功能,这是BeanFactory所不具备的

Spring中的事务是如何实现的

  1. Spring事务底层是基于数据库事务和AOP机制的
  2. ⾸先对于使⽤了@Transactional注解的Bean,Spring会创建⼀个代理对象作为Bean
  3. 当调⽤代理对象的⽅法时,会先判断该⽅法上是否加了@Transactional注解
  4. 如果加了,那么则利⽤事务管理器创建⼀个数据库连接
  5. 并且修改数据库连接的autocommit属性为false,禁⽌此连接的⾃动提交,这是实现Spring事务⾮常重要的⼀步
  6. 然后执⾏当前⽅法,⽅法中会执⾏sql
  7. 执⾏完当前⽅法后,如果没有出现异常就直接提交事务
  8. 如果出现了异常,并且这个异常是需要回滚的就会回滚事务,否则仍然提交事务
  9. Spring事务的隔离级别对应的就是数据库的隔离级别
  10. Spring事务的传播机制是Spring事务⾃⼰实现的,也是Spring事务中最复杂的
  11. Spring事务的传播机制是基于数据库连接来做的,⼀个数据库连接⼀个事务,如果传播机制配置为
    需要新开⼀个事务,那么实际上就是先建⽴⼀个数据库连接,在此新数据库连接上执⾏sql

Spring中什么时候@Transactional会失效

因为Spring事务是基于代理来实现的,所以某个加了@Transactional的⽅法只有是被代理对象调⽤时,那么这个注解才会⽣效,所以如果是被代理对象来调⽤这个⽅法,那么@Transactional是不会失效的。
同时如果某个⽅法是private的,那么@Transactional也会失效,因为底层cglib是基于⽗⼦类来实现的,⼦类是不能重载⽗类的private⽅法的,所以⽆法很好的利⽤代理,也会导致@Transactianal失效

  1. 不是代理对象被调用
  2. 方法不可访问(private)

Spring容器启动流程是怎样的

在创建Spring容器,也就是启动Spring时:

  1. 扫描Bean。⾸先会进⾏扫描,扫描得到所有的BeanDefinition对象,并存在⼀个Map中
  2. 创建Bean。然后筛选出⾮懒加载的单例BeanDefinition进⾏创建Bean,对于多例Bean不需要在启动过程中去进⾏创建,对于多例Bean会在每次获取Bean时利⽤BeanDefinition去创建
  3. 构造Bean。利⽤BeanDefinition创建Bean就是Bean的创建⽣命周期,这期间包括了合并BeanDefinition、推断构造⽅法、实例化、属性填充、初始化前、初始化、初始化后等步骤,其中AOP就是发⽣在初始化
    后这⼀步骤中
  4. 启动容器。单例Bean创建完了之后,Spring会发布⼀个容器启动事件。Spring启动结束
  5. 在源码中会更复杂,⽐如源码中会提供⼀些模板⽅法,让⼦类来实现,⽐如源码中还涉及到⼀些BeanFactoryPostProcessor和BeanPostProcessor的注册,Spring的扫描就是通过BenaFactoryPostProcessor来实现的,依赖注⼊就是通过BeanPostProcessor来实现的
  6. 在Spring启动过程中还会去处理@Import等注解

Spring⽤到了哪些设计模式

  1. 单例模式
  2. 工厂模式
  3. 模板方法模式
  4. 代理模式

这些比较容易理解的,还有其他的比如:责任链模式,观察者模式,面试中只需要完整的说出几个并举例即可

更多推荐

React antd Select 无法在disabled状态下选择并复制输入框内的内容情况分析及解决方案

文章目录背景问题分析解决思路一:会不会是由于在选择框内hover的时候出现的那个图标导致的解决思路二:会不会是这个span禁止复制解决思路三:去看看antd具体实现最终解决方案其他版本的解决方案antd3.*antd5.*背景在React项目开发中,我们经常会用到antd内的Select组件。有时候我们会在disabl

Eureka注册中心

文章目录1.Eureka的结构与作用2.搭建eureka-server服务3.注册service服务4.服务发现1.Eureka的结构与作用在Eureka架构中,微服务角色有两类:lEurekaServer:服务端,注册中心记录服务信息u心跳监控lEurekaClient:客户端Provider:服务提供者注册自己的信

数据结构前瞻

集合框架JAVA的集合框架是定义在java.util包下的一组接口和实现类,用于将多个元素置于一个单元中,对这些元素进行快速,便捷的存储,减速和管理,即增删查改下面的格子,黄色代表接口,蓝色代表抽象类,棕色代表类是动态数组(顺序表)优先级队列是双向列表底层就是一颗红黑树重要的四个接口算法效率时间复杂度即算法中基本操作的

2022年贵州省职业院校技能大赛中职组网络安全赛项规程

2022年贵州省职业院校技能大赛中职组网络安全赛项规程一、赛项名称赛项名称:网络安全赛项归属:信息技术类二、竞赛目的为检验中职学校网络信息安全人才培养成效,促进网络信息安全专业教学改革,培养大批既满足国家网络安全战略需要有具备世界水平的优秀技能人才,在社会上营造“技能改变命运、匠心成就人生”的崇尚技能的氛围,国家教育部

深入理解WPF中MVVM的设计思想

近些年来,随着WPF在生产,制造,工业控制等领域应用越来越广发,很多企业对WPF开发的需求也逐渐增多,使得很多人看到潜在机会,不断从Web,WinForm开发转向了WPF开发,但是WPF开发也有很多新的概念及设计思想,如:数据驱动,数据绑定,依赖属性,命令,控件模板,数据模板,MVVM等,与传统WinForm,ASP.

Redis实现Session持久化

Redis实现Session持久化1.前言直接使用Session存储用户登录信息,此时的会话信息是存储在内中的,只要项目重启存储的Session信息就会丢失。而使用Redis存储Session的话就不会存在这种情况,即使项目重启也并不影响,也无需用户重新登录。使用Redis存储Session,还能让项目支持分布式的,比

如何将 Transformer 应用于时间序列模型

在机器学习的广阔前景中,transformers就像建筑奇迹一样高高耸立,以其复杂的设计和捕获复杂关系的能力重塑了我们处理和理解大量数据的方式。自2017年创建第一个Transformer以来,Transformer类型呈爆炸式增长,其中包括ChatGPT和DALL-E等强大的生成式AI模型。虽然transformer

Beyong compare 介绍

"BeyondCompare"是一个强大的文件和文件夹比较工具,它允许你比较两个或更多的目录/文件并显示差异。这个工具特别有用,当你需要找出两个不同版本的文件之间的改变时。如果你想要使用BeyondCompare,你需要按照以下步骤操作:1.**下载和安装**:首先,你需要从BeyondCompare的官方网站或其他可

接口文档规范

接口文档规范主要包括以下几个方面:1.接口基本信息应该在文档的开头提供接口的基本信息,包括接口名称、接口URL、请求方法、请求参数、返回值、返回状态码等。这些信息应该清晰明了,并且易于理解。2.请求参数接口文档应该明确列出请求参数,并提供每个参数的名称、类型、是否必填、描述等信息。对于复杂结构的请求参数,例如JSON或

从网约车平台合规问题看企业合规难题如何破解

随着互联网的快速发展,网约车行业逐渐崛起并成为人们出行的重要选择之一。然而,虽然网约车平台带来了便利和效率,但也引发了一系列合规问题。近日,西安市交通运输综合执法支队和西安市出租汽车管理处组织开展了西安市网约车行业“全过程执法、全链条监管、全合规营运百日攻坚行动”。约谈会上,西安市出租汽车管理处相关负责人通报了“百日攻

华为OD机试真题 Java 实现【简易内存池】【2023 B卷 200分 考生抽中题】

目录一、题目描述二、输入描述三、输出描述样例:输出样例:四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明4、再输入5、再说明6、如果走后一次请求的是20,会怎么样呢?华为OD机试2023B卷题库疯狂收录中,刷题点这里一、题目描述请实现一个简易内存池,根据请求命令完成内存分配和释放。内存池支持两种操作

热文推荐