Spring AOP 完整详解
一、什么是 AOP1. 全称AOPAspect Oriented Programming 面向切面编程2. 核心思想纵向抽取重复通用逻辑横向切入业务代码解耦OOP面向对象纵向划分模块分层Controller/Service/Mapper解决业务核心逻辑AOP面向切面横向抽取通用非业务逻辑日志、事务、权限统一管理不侵入原有业务代码。3. 解决的痛点传统开发每个业务方法都重复写日志、事务、异常捕获代码冗余、耦合严重、修改麻烦。 AOP 方案把通用逻辑抽成切面在不改动业务代码前提下自动切入所有目标方法。二、AOP 七大核心概念必背1. JoinPoint 连接点程序中可以被切面拦截的点Spring AOP 仅支持方法执行作为连接点不支持字段、构造器。 例Service 层所有业务方法都是连接点。2. Pointcut 切点筛选匹配的连接点通过表达式规则精准定位要拦截哪些方法。 常用切点表达式java运行// 拦截com.service包下所有类的所有方法 execution(* com.service.*.*(..))连接点是全部候选切点是筛选后的子集。3. Advice 通知增强逻辑切面具体要执行的通用代码在切点方法的不同时机执行分 5 种Before 前置通知目标方法执行之前执行权限校验、参数日志AfterReturning 返回通知目标方法正常执行完毕、无异常后执行返回值日志AfterThrowing 异常通知目标方法抛出异常时执行异常告警、错误日志After 后置通知目标方法无论正常 / 异常最终都会执行资源释放Around 环绕通知包裹目标方法手动控制目标方法何时执行、是否执行最强大事务、耗时统计4. Aspect 切面切点 通知 的结合体一个切面 拦截规则Pointcut 通用增强逻辑Advice 开发中就是一个加了Aspect的类。5. Target 目标对象被切面拦截、增强的原始业务 Bean 对象。6. Proxy 代理对象AOP 底层通过动态代理生成的代理对象容器实际注入使用的是代理对象代理对象包含目标方法 切面增强逻辑。 Spring 两种代理实现JDK 动态代理目标类实现了接口基于接口代理CGLIB 代理目标类没有实现接口继承目标类生成子类代理 SpringBoot2.x 默认使用 CGLIB。7. Weaving 织入把切面的通知逻辑动态植入到目标对象方法的过程。 Spring AOP 是运行时织入容器创建 Bean 时生成代理完成织入。三、五种通知执行顺序Around 环绕前置代码Before 前置通知执行目标业务方法Around 环绕后置代码分两种分支方法正常返回After → AfterReturning方法抛出异常After → AfterThrowing四、AOP 典型应用场景工作 面试高频1. 统一日志处理最常用记录接口入参、出参、方法执行耗时、调用人不用每个方法手写日志。2. 事务管理Spring 核心场景Transactional底层就是 AOP 环绕通知 方法执行前开启事务正常执行提交事务出现异常回滚事务。3. 接口权限校验拦截 Controller 接口校验 token、登录状态、接口访问权限无权限直接拦截不执行业务。4. 全局异常统一处理捕获所有业务方法抛出的异常统一封装返回结果、记录错误日志、发送异常告警。5. 接口限流、防重复提交通过 AOP 拦截接口结合 Redis 实现接口限流、判断重复提交请求。6. 数据脱敏返回前端的数据自动脱敏手机号、身份证、银行卡隐藏部分数字。7. 缓存统一处理方法执行前查询缓存有缓存直接返回无缓存执行业务结果存入缓存。五、简单代码示例注解 AOPjava运行// 1. 切面类 Aspect Component public class LogAspect { // 切点拦截service包下所有方法 Pointcut(execution(* com.service.*.*(..))) public void pointCut(){} // 环绕通知统计方法耗时 Around(pointCut()) public Object around(ProceedingJoinPoint joinPoint) throws Throwable { long start System.currentTimeMillis(); // 执行目标方法 Object result joinPoint.proceed(); long cost System.currentTimeMillis() - start; System.out.println(方法执行耗时 cost ms); return result; } }六、高频面试延伸考点JDK 代理和 CGLIB 区别JDK要求目标类实现接口代理接口方法速度快CGLIB无需接口继承目标类生成子类无法代理 final 类 / 方法。AOP 和拦截器、过滤器区别Filter 过滤器Servlet 层面只拦截 http 请求不属于 SpringInterceptor 拦截器SpringMVC 层面拦截 ControllerAOP 切面Spring Bean 层面可拦截 Controller、Service、Mapper 所有 Bean 方法粒度更细。为什么循环依赖场景 AOP 代理提前生成正常 Bean 在初始化完成后生成代理存在循环依赖时为保证注入的是代理对象提前通过三级缓存 ObjectFactory 创建代理。