前言
- Spring 框架的两大核心设计思想是 IOC(控制反转) 和 AOP(面向切面编程)。
- 它们共同解决了代码耦合度高、重复逻辑冗余等问题。
IOC(控制反转)
1.核心概念
- 控制反转(Inversion of Control):将对象的创建、生命周期管理和依赖关系的控制权从应用程序代码转移给外部容器(如 Spring的IOC容器)。
- 依赖注入(Dependency Injection, DI):IOC 的具体实现方式,容器通过构造函数、Setter 方法或字段反射等方式,自动将依赖对象注入到目标对象中。
2.解决的问题
- 传统开发的问题:对象直接通过 new 创建依赖,导致代码高度耦合(如 Service 直接依赖 Dao 的具体实现)。
- IOC 的优势:
- 解耦:对象依赖由容器管理,开发者无需手动处理。
- 灵活配置:通过配置文件或注解动态替换实现类(如切换数据库驱动)。
- 资源复用:Spring 容器默认以单例模式管理 Bean,减少资源消耗。
3.实现方式
- XML 配置:通过 <bean标签定义 Bean 及其依赖。
- 注解驱动:如 @Component、@Autowired、@Service 等,简化配置。
- Java Config:使用 @Configuration 和 @Bean 以编程方式定义 Bean。
4.核心容器
- BeanFactory:基础容器,提供 Bean 的实例化和依赖注入。
- ApplicationContext:扩展了 BeanFactory,支持国际化、事件传播、AOP 等高级功能。
AOP(面向切面编程)
1.核心概念
- 横切关注点(Cross-Cutting Concerns):散布在多个模块中的公共逻辑(如日志、事务、权限校验)。
- AOP 的目标:将这些横切逻辑从业务代码中剥离,通过动态代理技术织入目标方法,实现代码复用和解耦。
2.关键术语
- 切面(Aspect):封装横切逻辑的类(如日志切面)。
- 连接点(JoinPoint):程序执行中的特定位置(如方法调用、异常抛出)。
- 切点(Pointcut):通过表达式匹配需要增强的连接点(如 execution( com.example.service…*(…)))。
- 通知(Advice):
- 前置通知(Before):在目标方法执行前执行。
- 后置通知(After):在目标方法执行后执行(无论是否异常)。
- 返回通知(AfterReturning):在目标方法正常返回后执行。
- 异常通知(AfterThrowing):在目标方法抛出异常后执行。
- 环绕通知(Around):包裹目标方法,可控制其执行过程。
3.实现原理
- JDK 动态代理:基于接口代理,要求目标类实现接口。
- CGLIB 动态代理:通过生成目标类的子类实现代理,适用于无接口的类。
- 织入(Weaving):将切面逻辑与目标类结合的时机,支持编译期、类加载期和运行期织入。
4.应用场景
- 日志记录:统一记录方法入参、出参和执行时间。
- 事务管理:通过 @Transactional 注解实现声明式事务。
- 权限校验:在方法执行前检查用户权限。
- 接口限流与幂等:防止重复提交或高并发场景下的资源争抢。
IOC和AOP的协同
- IOC 提供基础设施:Spring 容器管理 Bean 的创建和依赖,为 AOP 提供代理对象的生成环境。
- AOP 增强 Bean:通过动态代理技术,对容器管理的 Bean 进行功能扩展,实现非侵入式的逻辑增强。
代码示例
- 传统代码(高耦合)
- 当修改了实现类的名称时,所有代码中new该对象的地方都要修改,不易于维护
public class UserService {
private UserDao userDao = new UserDaoImpl();
public void saveUser() {
userDao.save();
}
}
@Service
public class UserService {
@Autowired
private UserDao userDao;
public void saveUser() {
userDao.save();
}
}
@Aspect
@Component
public class LogAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("方法执行: " + joinPoint.getSignature().getName());
}
}
总结
- IOC 通过控制反转和依赖注入,解决了对象间的强耦合问题。
- AOP 通过动态代理和切面编程,实现了横切逻辑的复用和解耦。
- 二者共同构建了 Spring 的轻量级、高扩展性架构,广泛应用于企业级开发。