首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
AOP引入:OOP存在哪些局限性?
AOP常见使用场景
AOP概念:Aspect、Join Point和Advice等术语应该如何理解?
Java AOP设计模式:代理、判断和拦截器模式
Java AOP代理模式(Proxy):Java静态代理和动态代理的区别是什么?
Java AOP判断模式(Predicate):如何筛选Join Point?
Java AOP拦截器模式(Interceptor):拦截执行分别代表什么?
Spring AOP 功能概述:核心特性、编程模型和使用限制
Spring AOP编程模型:注解驱动、XML配置驱动和底层API
Spring AOP设计目标:Spring AOP与 AOP框架之间的关系是竞争还是互补?
Spring AOP Advice类型:Spring AOP丰富了哪些AOP Advice呢?
Spring AOP代理实现:为什么Spring Framework选择三种不同AOP实现?
JDK动态代理:为什么Proxy.newProxyInstance会生成新的字节码?
CGLIB动态代理:为什么Java动态代理无法满足AOP的需要?
AspectJ代理代理:为什么Spring推荐AspectJ注解?
AspectJ基础:Aspect、Join Points、Pointcuts和Advice语法和特性
AspectJ注解驱动:注解能完全替代AspectJ语言吗?
Spring核心基础:《小马哥讲Spring核心编程思想》还记得多少?
@AspectJ注解驱动
编程方式创建 @AspectJ代理
XML配置驱动 - 创建AOP代理
标准代理工厂API - ProxyFactory
@AspectJ Pointcut指令与表达式:为什么Spring只能有限支持?
XML配置Pointcut
API实现Pointcut
@AspectJ拦截动作:@Around与@Pointcut有区别吗?
XML配置Around Advice
API实现Around Advice
@AspectJ前置动作:@Before与@Around谁优先级执行?
XML配置Before Advice
API实现Before Advice
@AspectJ后置动作 - 三种After Advice之间的关系?
XML配置三种After Advice
API实现三种After Advice
自动动态代理
替换TargetSource
Spring AOP API整体设计
接入点接口 - Joinpoint
Joinpoint条件接口 - Pointcut
Pointcut操作 - ComposablePointcut
Pointcut便利实现
Pointcut AspectJ实现 - AspectJExpressionPointcut
Joinpoint执行动作接口 - Advice
Joinpoint Before Advice标准实现
Joinpoint Before Advice AspectJ实现
Joinpoint After Advice标准实现
Joinpoint After Advice AspectJ实现
Advice容器接口 - Advisor
Pointcut与Advice连接器 - PointcutAdvisor
Introduction与Advice连接器 - IntroductionAdvisor
Advisor的Interceptor适配器 - AdvisorAdapter
AdvisorAdapter实现
AOP代理接口 - AopProxy
AopProxy工厂接口与实现
JDK AopProxy实现 - JdkDynamicAopProxy
当前位置:
首页>>
技术小册>>
Spring AOP 编程思想(上)
小册名称:Spring AOP 编程思想(上)
### 章节:XML配置三种After Advice 在Spring框架中,面向切面编程(AOP, Aspect-Oriented Programming)是一种强大的编程范式,它允许开发者将横切关注点(如日志、事务管理、安全等)从业务逻辑中分离出来,以增强代码的可维护性和模块化。Spring AOP提供了多种方式来实现切面,其中XML配置是早期Spring版本中广泛使用的一种。本章节将深入探讨如何在Spring中通过XML配置来实现三种常见的After Advice(后通知):After Returning Advice、After Throwing Advice和After (Finally) Advice。 #### 一、引言 在Spring AOP中,Advice是切面的动作部分,它定义了切面“做什么”以及“何时做”。根据通知执行的时机,可以将Advice分为多种类型,其中After Advice是在连接点(JoinPoint,通常是方法执行)之后执行的通知。After Advice进一步细分为三种类型: 1. **After Returning Advice**:在目标方法正常执行完成后执行。 2. **After Throwing Advice**:在目标方法抛出异常退出时执行。 3. **After (Finally) Advice**:无论目标方法是否抛出异常,都会在目标方法执行完毕后执行,类似于Java中的finally块。 #### 二、After Returning Advice After Returning Advice允许你在目标方法正常执行完成后执行一些操作,比如记录方法返回值、进行资源清理等。在XML配置中,你需要使用`<aop:after-returning>`元素来定义After Returning Advice。 ##### 示例配置 假设我们有一个服务类`UserService`,其中包含一个`saveUser`方法,我们想在这个方法执行成功后记录一些信息。 ```xml <beans ...> <!-- 定义切面 --> <bean id="loggingAspect" class="com.example.LoggingAspect"/> <!-- 配置AOP自动代理 --> <aop:config> <!-- 定义切入点 --> <aop:pointcut id="userServiceMethods" expression="execution(* com.example.service.UserService.*(..))"/> <!-- 配置After Returning Advice --> <aop:after-returning method="afterReturningAdvice" pointcut-ref="userServiceMethods" returning="result"/> </aop:config> </beans> ``` 在上面的配置中,`LoggingAspect`类必须包含一个`afterReturningAdvice`方法,该方法接受一个与`returning`属性指定的参数名相匹配的参数(本例中为`result`),用于接收目标方法的返回值。 ##### 切面类实现 ```java package com.example; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; // 注意:虽然示例中使用了@Aspect注解,但在XML配置中不需要该注解 public class LoggingAspect { // 注意:在XML配置中,不需要@AfterReturning注解 public void afterReturningAdvice(Object result) { System.out.println("方法执行成功,返回值为:" + result); } } ``` **注意**:在XML配置中,切面类的方法上不需要添加AOP注解,因为所有的配置都是通过XML来完成的。 #### 三、After Throwing Advice After Throwing Advice用于在目标方法抛出异常时执行特定的逻辑,如记录错误信息、回滚事务等。在XML中,通过`<aop:after-throwing>`元素来定义。 ##### 示例配置 继续上面的例子,我们想在`saveUser`方法抛出异常时记录错误信息。 ```xml <beans ...> <!-- 之前的配置保持不变 --> <!-- 配置After Throwing Advice --> <aop:after-throwing method="afterThrowingAdvice" pointcut-ref="userServiceMethods" throwing="ex"/> </beans> ``` 在`LoggingAspect`类中,你需要添加一个`afterThrowingAdvice`方法,它接受一个与`throwing`属性指定的参数名相匹配的参数(本例中为`ex`),用于接收抛出的异常。 ##### 切面类实现 ```java public class LoggingAspect { // 注意:在XML配置中,不需要@AfterThrowing注解 public void afterThrowingAdvice(Throwable ex) { System.out.println("方法执行时抛出异常:" + ex.getMessage()); } } ``` #### 四、After (Finally) Advice After (Finally) Advice无论目标方法是否成功执行,都会在其之后执行。这类似于Java中的finally块,用于执行必要的清理工作。在Spring AOP中,这种类型的Advice通过`<aop:after>`元素来定义,但需要注意的是,`<aop:after>`本身并不直接对应传统意义上的“finally”块,因为它不会捕获异常。然而,由于它总是执行,因此可以用作类似finally的功能。 ##### 示例配置 ```xml <beans ...> <!-- 之前的配置保持不变 --> <!-- 配置After Advice,作为类似Finally的功能 --> <aop:after method="afterAdvice" pointcut-ref="userServiceMethods"/> </beans> ``` 在`LoggingAspect`类中,添加`afterAdvice`方法,该方法不接受任何与返回值或异常相关的参数,因为它总是在目标方法执行完毕后执行。 ##### 切面类实现 ```java public class LoggingAspect { // 注意:在XML配置中,不需要特定注解 public void afterAdvice() { System.out.println("方法执行完毕,执行清理工作"); } } ``` #### 五、总结 通过XML配置Spring AOP的三种After Advice,我们能够将横切关注点从业务逻辑中分离出来,提高了代码的模块化和可维护性。After Returning Advice允许我们在方法成功执行后进行操作,After Throwing Advice则在方法抛出异常时执行,而After (Finally) Advice则提供了一种类似finally块的执行时机,用于执行必要的清理工作。尽管XML配置方式在Spring的较新版本中逐渐被注解配置所取代,但理解其原理对于深入学习Spring AOP仍具有重要意义。随着Spring Boot等现代框架的兴起,注解配置因其简洁性而变得更加流行,但XML配置在复杂项目或需要高度定制化配置的场景中仍然有其独特的价值。
上一篇:
@AspectJ后置动作 - 三种After Advice之间的关系?
下一篇:
API实现三种After Advice
该分类下的相关小册推荐:
Java语言基础11-Java中的泛型
Java必知必会-Maven高级
Java性能调优实战
Java语言基础8-Java多线程
Java并发编程
Java语言基础2-运算符
Java语言基础14-枚举和注解
手把手带你学习SpringBoot-零基础到实战
Java语言基础16-JDK8 新特性
SpringBoot合辑-高级篇
Mybatis合辑3-Mybatis动态SQL
Spring Cloud微服务项目实战