我梦笔记我梦笔记
Home
Home
  • MySQL
  • Java
  • JVM (黑马)
  • Spring
  • SpringBoot
  • Redis
  • 数据结构
  • 设计模式
  • Linux
  • Nginx
  • VUE.JS
  • Emby 伪站破解认证

Spring

IOC 控制反转

概念:把对 Bean 的控制权交给 Spring 容器。

循环依赖

Spring Bean 的循环依赖是通过三级缓存解决的。

假设有A、B、C三个bean,A引用B,B引用C,C引用A,spring就根据依赖关系把它们全都放到三级缓存里面,当创建C想把A注入到C里面的时候,发现A还在创建当中,一级缓存里面没有A,然后就从三级缓存里通过A的工厂获取A实例,把A实例提到二级缓存中,直接就把这个还没初始化的A注入到C当中,这样C就完成初始化了,然后把C提到一级缓存中,然后继续把C注入给B,把B注入回给A,这样就完成了ABC的初始化,这就是spring创建循环依赖的Bean的过程。

级别各级缓存的区别
一级SingletonObjects,存储单例对象,Bean 已经实例化、初始化
二级EarlySingletonObjects,存储 singletonObject,这个 Bean 实例化了,还没有初始化
三级SingletonFactories,存储 singletonFactory

Bean 的作用域

作用域描述
singleton以单例的形式存在,只有一个bean
prototype多实例,每次调用getBean()时会返回一个新的实例
request每次 HTTP 请求都创建一个新的bean
session一个session共用一个bean。不同session使用不同的bean

Bean 的生命周期

  1. 创建实例
  2. 属性赋值
  3. 初始化
  4. bean 正常使用
  5. 容器关闭,bean 销毁

单实例和多实例的不同

  • 单实例下 bean 的生命周期:

容器启动——>初始化方法——>(容器关闭)销毁方法

  • 多实例下 bean 的生命周期:

容器启动——>调用 bean ——>初始化方法——>容器关闭(销毁方法不执行)

Bean 属性的注入方式

  • 构造方法注入
  • setter 方法注入

部分设计模式

创建Bean的时候使用了单例模式、工厂设计模式

AOP 用到代理模式、适配器模式(功能增强和通知)

Spring 事务管理也是用到了代理模式,因为本质也是 AOP

Spring 事务

事务是数据库层面的,Spring 只是基于数据库事务进行扩展。Spring 中有两种事务实现方式:申明式 与 编程式,注解 @Transaction 就属于申明式。

Spring 事务隔离级别

隔离级别说明
read uncommitted未提交读
read committed已提交读、不可重复读
repeatable read可重复读
serializable可串行化

Mysql 默认的隔离级别是 可重复读

Oracle 和 SqlServer 都是已提交读

数据库配置的隔离级别是已提交读而 Spring 配置的隔离级别是可重复读,这个时候以 Spring 配置的为准,如果 Spring 设置的隔离级别数据库不支持那效果就取决于数据库本身。

@Transaction

Spring 会基于这个类生成一个代理对象,会将这个代理对象作为一个 bean 使用这个代理对象的方法。

提示

如果方法上存在 @transaction 注解,那么代理逻辑会先把事务的自动提交设置为false,然后再去执行原本业务逻辑方法,如果没有出现异常那么代理逻辑中就会将事务进行提交,如果执行业务中出现异常则会进行事务回滚。

Spring 默认会对 RuntimeException 和 Error 进行回滚,可以使用 rollback 属性配置。

事务传播机制

在 Spring 事务管理当中,对调用链中的子方法的事务处理策略叫做事务传播行为,也叫事务传播机制。

事务传播机制基本上就分为这3类:

  • 优先使用当前事务
  • 不适用当前事务,开启新的事务
  • 不使用任何事务
传播方式说明
Required如果当前没有事务,则自己新建一个事务,如果当前存在事务则加入这个事务(默认)
Supports当前存在事务则加入当前事务,如果当前没有事务,就以非事务方式执行
Mandatory当前存在事务则加入当前事务,如果当前没有事务就以非事务方法执行
never不适用事务,如果当前事务存在,则抛出异常
nested如果当前事务存在,则在嵌套事务中执行,否则Required的操作一样(开启一个事务)
Requires_new创建一个新事务,如果当前存在事务,则挂起该事务
Not_supported以非事务方式执行,如果当前存在事务,则挂起当前事务

Spring 事务什么时候会失效?

Spring 事务原理就是AOP进行切面增强,多数情况下原因是这个切面不生效了

  • 没有被 Spring 管理
  • 方法不是 public,事务 @Transaction 只能用于 public 方法上
  • 类内部自身调用,类里面使用this调用本类的方法(this通常省略),此时这个this对象不是代理类,而是原始类所以不生效 (解决: 将当前调用方法变成代理类)
  • 异常捕获或者是抛出异常没有被定义,默认为 RuntimeException
  • 数据库不支持
最近更新:: 2026/1/8 19:16
Contributors: womeng
Prev
JVM (黑马)
Next
SpringBoot