【重难点总结】第六章 Spring

【重难点总结】第六章 Spring

一、Spring 和 Spring Boot 的作用和对它们的理解

1.Spring

Spring 的核心思想是简化开发,通过依赖注入和 AOP,使得开发者可以更高效地构建企业级应用

2.Spring Boot

Spring Boot 是为了解决传统 Spring 应用开发过程中配置复杂、启动繁琐等问题设计的。通过简化配置、内嵌服务器、自动化配置、Starter 依赖等功能,极大地提高了开发效率

二、依赖注入

1.什么是依赖注入

依赖注入(Dependency Injection,DI)是 Spring 框架的核心概念之一,通过 DI,Spring 框架能够自动将对象的依赖项注入到对象中,使得对象不再需要自己创建或者查找其依赖项,这样可以降低代码的耦合度

2.底层原理

DI 是通过其核心组件 —— IoC(Inversion of Control)容器实现的。IoC 容器负责管理对象的创建、配置和生命周期,并根据配置将依赖项注入到对象中

Bean 定义与配置

Bean 是由 IoC 容器管理的对象。Bean 的定义可以通过 XML 文件、Java 注解或者 Java 配置类

BeanFactory 和 ApplicationContext

Spring 提供了两个核心接口来表示 IoC 容器:BeanFactory 和 ApplicationContext
BeanFactory 是 Spring 的基础 IoC 容器,提供基本的依赖注入功能。而 ApplicationContext 是 BeanFactory 的扩展,提供更高级的特性,比如 AOP 集成
ApplicationContext 在应用启动时,会读取配置文件或注解,解析 Bean 定义,并在需要时实例化和初始化 Bean

依赖注入过程

  • 解析配置:ApplicationContext 会解析配置文件(XML、Java 配置类)或扫描注解以识别所有的 Bean 定义
  • 实例化 Bean:当需要某个 Bean 时,容器会首先检查该 Bean 是否已经实例化。如果没有实例化,容器会根据 Bean 的定义创建一个新的实例
  • 注入依赖:在实例化 Bean 后,容器会根据配置或注解注入依赖项,构造函数、Setter 方法、字段等
  • 初始化 Bean:如果 Bean 实现了 InitializingBean 接口,容器会调用其 afterPropertiesSet 方法进行初始化。如果配置了初始化方法(如 ‘init-method’),容器也会调用该方法
  • 将 Bean 提供给请求者:注入依赖和初始化完成后,容器会将 Bean 提供给请求者

反射机制

Spring 的依赖注入依赖于 Java 的反射机制。通过反射,Spring 可以在运行时动态地创建对象、调用构造函数、设置属性值和调用方法。反射使得 Spring 能够灵活地管理对象及其依赖项,而不需要在编译时确定所有的依赖关系

代理与 AOP

为了支持 AOP,Spring 会为这些 Bean 创建代理对象

3.设计模式

工厂模式

工厂模式通过一个工厂类来负责创建对象实例,并对创建逻辑进行封装。Spring IoC 容器实际上就是一个大型的工厂,负责创建和管理 Bean 实例

BeanFactory 和 ApplicationContext 都是工厂模式的应用,通过这些工厂类,Spring 容器能够根据配置文件或注解创建和管理 Bean 实例

单例模式

单例模式确保一个类只有一个实例,并提供一个全局访问点。Spring 容器默认以单例模式管理 Bean,确保每个 Bean 在容器中只有一个实例

4.循环依赖

循环依赖发生在两个或多个 Bean 互相依赖的情况,导致 Spring 创建 A 的时候需要创建 B,创建 B 的时候又需要创建 A

Spring 通过三级缓存解决单例作用域的循环依赖问题,但是无法解决 prototype 作用域的循环依赖问题,开发者可以通过避免使用构造函数或者属性注入的方式,而是通过方法调用来获取另一个 prototype Bean 的实例

三级缓存

  • singletonObjects:存储完全初始化好的单例 Bean
  • earlySingletonObjects:存储原始的、实例化但尚未初始化的单例 Bean
  • singletonFactories:存储 Bean 工厂,用于创建代理对象或原始对象

解决循环依赖的步骤

  • 创建 Bean 实例:当 Spring 需要创建一个单例 Bean 时,首先检查 singletonObjects 缓存中是否已经存在该 Bean 实例
  • 提前暴露:如果 Bean A 依赖于 Bean B,而 Bean B 又依赖于 Bean A,Spring 首先会实例化 Bean A,但不会立即初始化(调用构造函数和依赖注入)。然后 Spring 将 Bean A 的 ObjectFactory 存放到 singletonFactories 和 earlySingletonObjects 中
  • 填充属性:当填充 Bean A 的属性时,发现 Bean A 依赖于 Bean B,Spring 会递归创建 Bean B;为了避免无限递归,Spring 会检查 singletonObjects 缓存和 earlySingletonObjects 缓存中是否已经存在 Bean B 的实例;如果存在,直接返回 Bean B 的实例。如果不存在,创建 Bean B 的实例,并将其放入 earlySingletonObjects 缓存中
  • 初始化 Bean:当 Bean B 初始化完成后,再回到 Bean A,并完成其初始化过程;最终,将 Bean A 和 Bean B 分别放入 singletonObjects 缓存中,从而完成循环依赖的解决

三、AOP

1.什么是 AOP

AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在增强和分离关注点(concerns)的实现,通过将横切关注点从核心业务逻辑中分离出来,以提高代码的模块化程度和可重用性。将与切面的代码集中在一个地方管理,便于维护和修改。通过切面将关注点与业务逻辑分离,减少模块间的耦合,提高了系统的灵活性和可扩展性

2.底层原理

切点

切点定义了切面在何处执行通知。在 AOP 中,切点使用一种特定的表达式语言(如 AspectJ 表达式)来描述需要拦截的连接点。连接点可以是方法调用、方法执行、异常处理等

通知

通知定义了切面在切点处执行的具体逻辑。Spring AOP 提供了几种常见的通知类型:

  • 前置通知:在目标方法执行之前执行
  • 后置通知:在目标方法正常返回后执行
  • 异常通知:在目标方法抛出异常后执行
  • 最终通知:无论目标方法是否正常返回或抛出异常都执行
  • 环绕通知:包围目标方法的整个执行过程,可以在方法执行前后都执行额外的逻辑

织入

织入是指将切面的通知应用到目标对象的方法中的过程。织入可以发生在编译器、类加载期或者运行期间:

  • 编译期织入:在编译阶段通过特定的编译器进行织入,生成经过增强的字节码文件。AspectJ 支持编译期织入
  • 类加载期织入:在类加载到 JVM 时通过特定的类加载器进行字节码增强,AspectJ 也支持这种方式
  • 运行期织入:在应用程序运行时动态地将切面织入到目标对象中,Spring AOP 主要采用这种方式,通过动态代理实现织入

AOP Proxy

Spring AOP 使用 AOP Proxy 来管理切面和目标对象之间的交互。AOP Proxy 是代理对象的抽象,它包装了目标对象,并拦截了目标方法的调用,执行切面的通知逻辑

@Aspect
@Component
public class LoggingAspect {
   

	@Around("execution(* com.example.service.*.*(..))"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

313YPHU3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值