深入理解Spring:Spring

目录

1、Spring介绍

1.1、什么是 Spring Framework

1.2、Spring的8类模块

1.3、Spring用到哪些设计模式

1.4、Spring异常处理机制

1.5、Spring自动装配

2、Spring循环依赖

2.1、什么是循环依赖,什么情况出现

2.2、如何解决循环依赖

2.2.1、Spring自己的三级缓存解决

2.2.2、为什么使用三级缓存而不是二级缓存

2.2.3、为什么不只使用一级缓存

2.2.4、@Lazy注解解决

3、Spring事物

3.1、什么是事物

3.2、Spring中事物的实现/管理方式

3.2、Spring中事物的隔离级别(5个)

3.3、Spring事物的传播机制/行为


1、Spring介绍

1.1、什么是 Spring Framework

就是一个框架,简称Spring。提供一系列功能和特性,例如依赖注入、控制反转、面向切面编程、事物管理、数据访问、MVC等。

1.2、Spring的8类模块

(1)核心模块(Spring  Core):

  • Spring Beans:  提供IOC和DI服务,其他模块都依赖它;
  • Spring Core:  核心类库,所有功能都依赖该类库;
  • Spring Context:  是BeanFactory的扩展,提供更多功能如国际化、资源管理
  • SpEL:表达式语言,例如@、#、{}、AOP切面表达式、XML的<>等

(2)数据存储模块:Spring JDBC、ORM等

(3)Web模块:WebSocket、MVC等

(4)Spring AOP模块:面向切面编程

(5)Test测试模块:提供对单元测试、集成测试、端到端测试的支持

(6)Instrumentation模块:Java代理API,用于监控和管理JVM虚拟机上的应用程序

(7)Messaging模块:消息模块

(8)Aspects模块:Aspects提供更高级面向切面编程的框架,可以和其他模块集成

1.3、Spring用到哪些设计模式

  • 工厂设计模式 : Spring使用工厂模式通过 BeanFactoryApplicationContext 创建 bean 对象。

  • 代理设计模式 : Spring AOP 功能的实现。

  • 单例设计模式 : Spring 中的 Bean 默认都是单例的。

  • 模板方法模式 : Spring 中 jdbcTemplatehibernateTemplate 等以 Template 。

  • 策略模式 : Resource资源获取实现类,针对不同的资源实现不同的资源获取策略,如UrlResource、ClassPathResource

  • 适配器模式 :Spring MVC 中用到了适配器模式适配Controller

1.4、Spring异常处理机制

主要集中在Spring MVC模块中,用于处理Web应用程序中的异常情况。 异常分为编译时异常和运行时异常,编译时异常我们 try-cache 进行捕获后自行处理,而运行时异常是不可预期的。

(1)全局异常处理器

(2)自定义异常处理

(3)@ExceptionHandler等注解捕获异常处理

1.5、Spring自动装配

参考:深入理解Spring:Bean---4、bean自动装配几种方式

2、Spring循环依赖

2.1、什么是循环依赖,什么情况出现

类与类之间的依赖关系形成了闭环。循环依赖问题在Spring中有以下三种情况:

(1)通过构造方法注入时产生循环依赖;

(2)通过Setter方法注入且是 多例 模式下产生循环依赖;

(3)通过Setter方法注入且是单例模式下产生循环依赖---已解决(只有这种被解决了)

其他2种都会异常,因为

第一种在new对象的时候会堵塞住;例如Bean A-->Bean B -->Bean C Spring先创建C,接着创建B(将C注入B),最后创建A(将B注入A),当存在循环依赖时Spring无法决定先创建哪个Bean,就会报错。该方式经常发生循环依赖。

第二种每一次在getBean()的时候都会产生一个新的Bean,如此反复下去就会有无数个Bean产生,最终导致OOM;

2.2、如何解决循环依赖

2.2.1、Spring自己的三级缓存解决

通过二级缓存和三级缓存解决,三级缓存是重点。核心思想是在对象实例化之后,依赖注入之前,Spring提前暴露 Bean实例的引用也就是代理对象 在第三集缓存中进行存储。

2.2.2、为什么使用三级缓存而不是二级缓存

  • 一级缓存(singletonObjects)存放已经创建并初始化完的Bean实例;
  • 二级缓存(earlySingletonObjects)存放已经创建但未初始化的Bean实例;
  • 三级缓存(singletonFactories)存放用于创建Bean的代理对象ObjectFactory,该缓存只对内使用,Spring框架内部逻辑使用该缓存。

当循环依赖存在时,两个Bean都存在二级缓存中等待对方创建完成,将导致死锁的发生。三级缓存允许在循环依赖时暂时存储已经创建但未初始化的Bean实例,并且通过ObjectFactory代理对象工厂来延迟创建Bean的实例,这样可以避免二级缓存的死锁问题。

触发解决循环依赖时Spring从三级缓存获取代理对象ObjectFactory并使用他创建Bean实例,提前暴露Bean对象的引用(实例化之后,依赖注入之前),然后将该实例放入以及缓存中,并最终初始化完成

(三个缓存是彼此互斥的,一个Bean只会存在一个地方,读取顺序为一、二、三)

2.2.3、为什么不只使用一级缓存

一级缓存设置存放创建和初始化完整的Bean对象,如果存在完整和不完整的则会丢失存储,违反了设计原则

2.2.4、@Lazy注解解决

主要解决构造函数相互注入的循环依赖。前面的是Spring自动解决单例模式下Settter()方法注入的循环依赖,而构造方法造成的无法自动解决。

使用方法:A类和B类都是通过构造器注入的,可在A或B构造函数形参加@Lazy注解实现延迟加载

实现原理:当实例化对象时发现参数或者属性有@Lazy注解修饰,就不直接创建所依赖的对象了而是用动态代理创建一个代理类,这样就不是直接依赖而是依赖代理类了(例如A a=new A(B))。

3、Spring事物

3.1、什么是事物

Spring事物其实就是数据库的事物,Spring自己没事物,它只提供统一事物管理接口,具体事物由不同数据库自己实现,redo log: 数据库事物提交、undo log:数据库事物回滚。是一组操作要么全部完成要么全部不完成

3.2、Spring中事物的实现/管理方式

(1)编程式事物:在代码中硬编码(不推荐使用);

(2)声明式事物:在配置文件中配置(推荐使用,建立在AOP之上)——分为两种

  • 基于XML的声明式事物;
  • 基于注解(@Transactiona)的声明式事物。

(本质是通过AOP对方法前后进行拦截,将事物处理功能编织到拦截方法中,在目标方法之前启动一个事物,在执行完目标方法之后根据执行情况提交或者回滚事物)

3.2、Spring中事物的隔离级别(5个)

  • 默认;
  • 最低隔离级别(脏读、幻读、不可重复读)——读取未提;
  • Oracle默认(幻读、不可重复读)——读取已提交;
  • MySQL默认——可重复读(幻读);
  • 最高隔离级别——可串行化

3.3、Spring事物的传播机制/行为

定义了在一个事务方法调用另一个事务方法时,新方法如何参与现有事务的规则。

这些传播行为可以通过 @Transactional 注解的属性来指定:

(1)required(默认):如果当前存在事务,则加入该事务,如果没有事务则新建一个事务

(2)required_new:无论当前是否存在事务,都会开启一个新的事务,如果已存在事务则将当前事务挂起。

(3)supports:如果当前存在事务,则加入该事务,如果没有事务则以非事务的方式执行

(4)no_supported:以非事务的方式执行操作,如果当前存在事务,则将其挂起

(5)never:要求当前不存在事务,如果存在则抛出异常

​  参考资料:《Spring技术内幕》

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值