Spring
Spring
核心特性
- IoC 容器:Spring 通过控制反转实现了对象的创建和对象间的依赖关系管理。开发者只需要定义好 Bean 及其依赖关系,Spring 容器负责创建和组装这些对象。
- AOP:面向切面编程,允许开发者定义横切关注点,例如事务管理、安全控制等,独立于业务逻辑的代码。通过 AOP 可以将这些关注点模块化,提高代码的可维护性和可重用性。
- 事务管理:Spring 提供了一致的事务管理接口,支持声明式和编程式事务。开发者可以轻松地进行事务管理,而无需关心具体的事务 API。
- MVC 框架:Spring MVC 是一个基于 Servlet API 构建的 Web 框架,采用了模型-视图-控制器(MVC)架构。它支持灵活的 URL 到页面控制器的映射,以及多种视图技术。
核心思想
| 核心思想 | 解决的问题 | 实现手段 | 典型应用场景 |
|---|---|---|---|
| IoC | 对象创建与依赖管理的高耦合 | 容器管理 Bean 生命周期 | 动态替换数据库实现、服务组装 |
| DI | 依赖关系的硬编码问题 | Setter/构造器/注解注入 | 注入数据源、服务层依赖 DAO 层 |
| AOP | 横切逻辑分散在业务代码中 | 动态代理与切面配置 | 日志、事务、权限校验统一处理 |
- IoC:控制反转,创建和获取对象的技术思想
- 依赖注入(DI)是实现这种技术的一种方式。
- 传统开发过程中通过 new 关键字来创建对象。
- 使用 IoC 思想开发方式,不通过 new 关键字创建对象,而是通过 IoC 容器来实例化对象,可以降低对象之间的耦合度。
- AOP:面向切面编程,将与业务无关,却为业务模块所共同调用的逻辑封装起来,以减少系统的重复代码,降低模块间的耦合度。
- Spring AOP 基于动态代理的,如果要代理的对象实现了指定接口,Spring AOP 就会使用 JDK Proxy 创建代理对象
Spring IoC
概念
IOC:Inversion Of Control,即控制反转,是一种设计思想。在传统的 Java SE 程序设计中,会直接在对象内部通过 new 的方式来创建对象,是程序主动创建依赖对象

而在 Spring 程序设计中,IOC 是有专门的容器去控制对象。

控制就是对象的创建、初始化、销毁。
- 创建对象:原来是
new,现在是由 Spring 容器创建。 - 初始化对象:原来是对象自己通过构造器或者
setter方法给依赖的对象赋值,现在是由 Spring 容器自动注入。 - 销毁对象:原来是直接给对象赋值
null或做一些销毁操作,现在是 Spring 容器管理生命周期负责销毁对象。
实现机制
- 反射:Spring IOC 容器利用 Java 的反射机制动态地加载类、创建对象实例及调用对象方法,反射允许在运行时检查类、方法、属性等信息,从而实现灵活的对象实例化和管理。
- 依赖注入:IOC 的核心概念是依赖注入,即容器负责管理应用程序组件之间的依赖关系。Spring 通过构造函数注入、属性注入或方法注入,将组件之间的依赖关系描述在配置文件中或使用注解。
- 设计模式 - 工厂模式:Spring IOC 容器通常采用工厂模式来管理对象的创建和生命周期。容器作为工厂负责实例化 Bean 并管理它们的生命周期,将 Bean 的实例化过程交给容器来管理。
- 容器实现:Spring IOC 容器是实现 IOC 的核心,通常使用 BeanFactory 或 ApplicationContext 来管理 Bean。BeanFactory 是 IOC 容器的基本形式,提供基本的 IOC 功能;ApplicationContext 是 BeanFactory 的扩展,并提供更多企业级功能。
IoC 设计
假设重构一套 IoC 方案,需要考虑:
- Bean 的生命周期管理:需要设计 Bean 的创建、初始化、销毁等生命周期管理机制,可以考虑使用工厂模式和单例模式来实现。
- 依赖注入:需要实现依赖注入的功能,包括属性注入、构造函数注入、方法注入等,可以考虑使用反射机制和 XML 配置文件来实现。
- Bean 的作用域:需要支持多种 Bean 作用域,比如单例、原型、会话、请求等,可以考虑使用 Map 来存储不同作用域的 Bean 实例。
- AOP 功能的支持:需要支持 AOP 功能,可以考虑使用动态代理机制和切面编程来实现。
- 异常处理:需要考虑异常处理机制,包括 Bean 创建异常、依赖注入异常等,可以考虑使用 try-catch 机制来处理异常。
- 配置文件加载:需要支持从不同的配置文件中加载 Bean 的相关信息,可以考虑使用 XML、注解或者 Java 配置类来实现。
Spring DI
在传统编程中,当一个类需要使用另一个类的对象时,通常会在该类内部通过new关键字来创建依赖对象,这使得类与类之间的耦合度较高。
而依赖注入则是将对象的创建和依赖关系的管理交给 Spring 容器来完成,类只需要声明自己所依赖的对象,容器会在运行时将这些依赖对象注入到类中,从而降低了类与类之间的耦合度,提高了代码的可维护性和可测试性。
Spring 中,常见的依赖注入:构造器注入、Setter 方法注入、字段注入
注入方式
构造器注入
通过构造函数传递依赖对象,保证对象初始化时依赖已就绪
@Service
public UserService {
private final UserRepository userRepository;
// 构造器注入(Spring 4.3+ 自动识别单构造器,无需显式@Autowired)
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
Setter 注入
通过 Setter 方法设置依赖,灵活性高,但依赖可能未完全初始化。
public class PaymentService {
private PaymentGateway gateway;
@Autowired
public void setGateway(PaymentGateway gateway) {
this.gateway = gateway;
}
}
字段注入
直接通过 @Autowired(或 @Resource) 注解字段,代码简洁但隐藏依赖关系,不推荐生产代码
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
}
Spring AOP
AOP 能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
概念
- AspectJ:切面,只是一个概念,没有具体的接口或类与之对应,是 Join point,Advice 和 Pointcut 的一个统称。
- Join point:连接点,指程序执行过程中的一个点,例如方法调用、异常处理等。在 Spring AOP 中,仅支持方法级别的连接点。
- Advice:通知,即定义的一个切面中的横切逻辑,有“around”,“before”和“after”三种类型。在很多的 AOP 实现框架中,Advice 通常作为一个拦截器,也可以包含许多个拦截器作为一条链路围绕着 Join point 进行处理。
- Pointcut:切点,用于匹配连接点,一个 AspectJ 中包含哪些 Join point 需要由 Pointcut 进行筛选。
- Introduction:引介,让一个切面可以声明被通知的对象实现任何他们没有真正实现的额外的接口。例如可以让一个代理对象代理两个目标类。
- Weaving:织入,在有了连接点、切点、通知以及切面后,在切点的引导下,将通知逻辑插入到目标方法上,使得通知逻辑在方法调用时得以执行。
- AOP proxy:AOP 代理,指在 AOP 实现框架中实现切面协议的对象。在 Spring AOP 中有两种代理,分别是 JDK 动态代理和 CGLIB 动态代理。
- Target object:目标对象,就是被代理的对象。
实现机制
Spring AOP 的实现依赖于动态代理技术。动态代理是在运行时动态生成代理对象,而不是在编译时。它允许开发者在运行时指定要代理的接口和行为,从而实现在不修改源码的情况下增强方法的功能。
Spring AOP 支持两种动态代理:
- 基于 JDK 的动态代理:使用
java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口实现。这种方式需要代理的类实现一个或多个接口。 - 基于 CGLIB 的动态代理:当被代理的类没有实现接口时,Spring 会使用 CGLIB 库生成一个被代理类的子类作为代理。CGLIB(Code Generation Library)是一个第三方代码生成库,通过继承方式实现代理。
静态代理
动态代理
反射
循环依赖问题
三级缓存
设计模式
常用注解
事务
Bean
生命周期
单例
作用域
加载/销毁前后逻辑
容器
扩展
SpringMVC
MVC 分层
处理流程
HandlerMapping
HandlerAdapter
SpringBoot
为什么使用
设计模式
约定大于配置
项目结构
自动装配原理
启动器 Starter
相关注解
事务
过滤器和拦截器
原理
MyBatis
传统 JDBC
JDBC 连接数据库
原生 MyBatis
# 和 $
MyBatisPlus
MyBatis 的设计模式
SpringCloud
微服务组件
负载均衡算法
服务熔断
服务降级
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 木素音的小站!