Spring AOP

一、Spring AOP 是什么?

Spring AOP(Aspect-Oriented Programming in Spring) 是 Spring 框架提供的基于代理的面向切面编程实现。它允许开发者将横切关注点(如日志、事务、安全、监控等)从核心业务逻辑中剥离,以声明式方式织入到 Spring 管理的 Bean 中。

二、Spring AOP 的核心组件

1. Aspect(切面):

一个被 @Aspect 注解标记的 Spring Bean,用于模块化横切关注点(即封装 Pointcut 和 Advice 的容器)。

2. Pointcut(切点):

一个表达式,用于定义在哪些方法(Join Point)上应用通知(Advice)。

3. Advice(通知):

在切点匹配的方法执行前后(或周围)运行的具体增强逻辑,如前置、后置、环绕等。

4. JoinPoint(连接点):

程序执行过程中可被拦截的具体点(在 Spring AOP 中特指方法的执行),通过它可获取方法签名、参数等上下文信息。

三、Spring AOP 的工作原理

在 Spring 容器启动时,通过 BeanPostProcessor 检查被管理的 Bean 是否匹配切面(Aspect)中定义的切点(Pointcut),若匹配,则基于 JDK 动态代理(目标类实现接口时)或 CGLIB 代理(未实现接口或强制启用时)动态生成代理对象;当调用该 Bean 的方法时,实际执行的是代理对象的逻辑,代理会按照 @Order 顺序组织通知(Advice)形成拦截链,在目标方法执行前后依次触发前置、环绕、返回、异常和后置通知,从而实现横切逻辑的透明织入。整个过程完全在运行时完成,仅支持对 Spring 管理的 Bean 的方法调用进行拦截。

四、五种通知类型详解

1. @Before:在目标方法执行前运行,用于前置检查或日志,无法阻止方法执行(除非抛异常)。

2. @After:在目标方法执行后无论成功或异常都运行,类似 finally 块,用于资源清理。

3. @AfterReturning:仅在目标方法成功返回后运行,可访问并处理返回值。

4. @AfterThrowing:仅在目标方法抛出异常后运行,可捕获并处理异常。

5. @Around:完全包围目标方法,可控制是否执行、修改参数/返回值、捕获异常,功能最强大。

五、切点表达式

1. execution():用于精确匹配方法的执行,通过指定返回类型、包路径、类名、方法名和参数列表(支持通配符 * 和 ..),可灵活定位到特定方法或方法集合,是 Spring AOP 中最常用、最强大的切点表达式。

2. @annotation():用于匹配方法上直接标注了指定注解的连接点,只需提供注解的全限定类名,特别适合实现声明式 AOP 功能(如自定义 @Log、@Cacheable 等),使切面逻辑与业务代码解耦且语义清晰。

六、Spring AOP 的限制与陷阱

1. 仅支持对 Spring 容器管理的 Bean 的方法执行进行拦截,无法处理字段访问、构造器调用等

2. 同类方法自调用(this.method())会绕过代理,导致 AOP 失效;

     目标类或方法若为 final,CGLIB 代理将失败;

     未实现接口的类需依赖 CGLIB,可能引发兼容性问题;

     多个切面未显式指定 @Order 时执行顺序不确定;

     切点表达式过于宽泛易引发性能或逻辑错误。因此,必须确保被增强对象是 Spring Bean、避免内部直接调    用合理设计切点并明确切面顺序。

七、Spring AOP 常见失效场景

1. 切点表达式有误:纠正即可

2. 不是spring管理的bean:将bean交给spring管理

3. 内部方法调用:将当前 Bean 通过 @Autowired 注入自己或者使用 AopContext.currentProxy()(需开启 exposeProxy)

4. 异步方法:将该 AOP 方法拆分到另一个 Spring 管理的 Bean 中,并通过注入该 Bean 的方式调用,从而确保走代理链、使 AOP 生效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值