一、IOC(控制反转):反转对象的创建权
1. 核心概念
IOC的核心是“将对象的创建、管理和依赖关系的维护交给容器”,而非由开发者在代码中手动new对象。开发者只需定义对象的“蓝图”(如类、依赖关系),容器(Spring容器)会自动完成对象的创建和组装。
2. 传统开发模式 vs IOC模式
传统模式:
假设开发一个用户服务(UserService),它依赖于数据访问层(UserDao),代码如下:
1 | // 数据访问层 |
问题:
- 依赖关系硬编码(
new UserDao()),如果UserDao的实现变更(如从MySQLDao改为OracleDao),需要修改UserService的代码,违反“开闭原则”。 - 对象创建和管理分散在代码各处,不利于统一控制(如单例、生命周期管理)。
IOC模式:
通过Spring容器管理对象,开发者只需声明依赖关系:
1 | // 1. 定义组件(交给Spring管理) |
改进:
- 依赖关系由Spring自动注入(
@Autowired),UserService不再关心UserDao的创建细节,实现了解耦。 - 若需更换
UserDao的实现(如UserDaoImpl),只需修改UserDao的实现类,无需改动UserService,符合“开闭原则”。
3. IOC在项目中的作用
- 解耦:消除对象间的硬编码依赖,降低模块间耦合度。
- 集中管理:容器统一管理对象的创建、生命周期(如单例/多例)、初始化/销毁,简化开发。
- 灵活性:通过配置(注解或XML)轻松切换依赖实现,适应需求变化。
二、AOP(面向切面编程):分离交叉关注点
1. 核心概念
AOP的核心是“将分散在多个模块中的重复代码(如日志、事务、权限校验)抽取为独立的“切面”,在不修改原有代码的前提下,动态织入到目标方法中”。这些重复代码被称为“交叉关注点”。
2. 传统开发模式 vs AOP模式
传统模式:
在多个业务方法中添加日志打印(记录方法调用时间、参数):
1 |
|
问题:
- 日志代码与业务代码混杂,违背“单一职责原则”(一个方法只做一件事)。
- 若需修改日志格式,需修改所有包含日志的方法,维护成本高。
AOP模式:
将日志代码抽取为切面,通过Spring AOP织入目标方法:
1 | // 1. 定义切面(日志功能) |
改进:
- 日志代码与业务代码完全分离,业务类专注于核心逻辑,符合“单一职责原则”。
- 若需修改日志逻辑,只需修改
LogAspect,无需改动业务类,维护成本极低。
3. AOP在项目中的作用
- 分离关注点:将非核心逻辑(日志、事务、权限)从业务代码中剥离,提高代码可读性和可维护性。
- 代码复用:交叉关注点只需实现一次,通过切面织入到多个目标方法,避免重复编码。
- 动态增强:无需修改原有代码,即可在运行时为方法添加额外功能(如事务回滚、异常处理)。
三、IOC与AOP结合解决实际问题
场景:电商订单系统中的“下单”功能
需求:
- 下单时需校验用户权限(未登录用户不能下单)。
- 记录下单操作的日志(方法参数、耗时)。
- 保证下单过程的事务一致性(库存扣减和订单创建需同时成功或失败)。
传统开发模式的问题:
- 权限校验、日志、事务代码会嵌入到
OrderService的createOrder方法中,导致代码臃肿。 - 若其他业务(如“取消订单”)也需要这些功能,需重复编写代码。
IOC + AOP的解决方案:
- IOC:管理
OrderService、UserDao、OrderDao等对象的依赖关系,通过@Autowired自动注入,避免硬编码。 - AOP:
- 权限校验切面:拦截下单方法,校验用户是否登录,未登录则抛出异常。
- 日志切面:记录下单方法的参数、执行时间。
- 事务切面:通过
@Transactional注解(Spring的声明式事务基于AOP实现)保证事务一致性。
代码示例:
1 | // 1. 业务层:订单服务(仅核心逻辑) |
价值体现:
- IOC:
OrderService无需手动创建OrderDao和InventoryDao,依赖关系由容器管理,降低耦合。 - AOP:权限校验、日志、事务逻辑与下单核心业务分离,代码清晰;若后续需修改权限规则或日志格式,只需调整对应切面,不影响业务代码。
- 扩展性:若新增“订单超时取消”功能,只需在新方法上添加
@Transactional和日志切面,无需重复开发非核心逻辑。
总结
- IOC 解决了“对象依赖管理”的问题,通过容器反转控制,实现模块解耦和集中管理。
- AOP 解决了“交叉关注点复用”的问题,通过切面分离非核心逻辑,提升代码可维护性。
- 两者结合是Spring的核心竞争力:IOC为AOP提供了对象管理的基础(切面和目标对象均由容器管理),AOP则基于IOC实现了无侵入式的功能增强,共同支撑起灵活、可扩展的企业级应用开发。