AOP中Advice执行两遍的原因

本文探讨了Spring项目中AOP Advice为何会执行两次的问题。解析了原因在于切面被错误地应用到了接口而非其实现类上,并提供了正确的配置指导。

spring项目中,Aop的Advice执行了两边,就好像拦截了两遍一样。

原因是:切面应该切到接口的实现类上,而不是接口上

转载于:https://www.cnblogs.com/doudouxiaoye/p/5697620.html

<think>首先,用户的问题是关于SpringAOPAdvice接口的继承结构。我需要基于提供的引用内容来回答,这些引用是关于SpringAOP的。回顾引用内容:-引用[1]:提到引入AOP依赖和切入点表达式。-引用[2]:解释了AOP编程的关键是定义切入点和增强处理,并给出了一个实现MethodBeforeAdvice,AfterReturningAdvice,MethodInterceptor的例子。-引用[3]:讨论了多个切面切入一个目标类,使用@Order注解来控制执行顺序。用户的问题焦点是Advice接口的继承结构。从引用[2]中,我看到它提到了几个接口:MethodBeforeAdvice,AfterReturningAdvice,MethodInterceptor。这些是SpringAOP中的核心Advice接口。在SpringAOP中,Advice接口是通知的基础。通知类型包括:Beforeadvice,Afterreturningadvice,Afterthrowingadvice,After(finally)advice,和Aroundadvice。继承结构:-顶层接口可能是org.aopalliance.aop.Advice,这是AOP联盟定义的接口。-Spring扩展了这个:-Beforeadvice:MethodBeforeAdvice-Afterreturningadvice:AfterReturningAdvice-Afterthrowingadvice:ThrowsAdvice-Aroundadvice:MethodInterceptor(来自AOP联盟)MethodInterceptor是Aroundadvice的实现。在引用[2]的例子中,它实现了MethodBeforeAdvice,AfterReturningAdvice,和MethodInterceptor。我应该描述继承层:-Advice接口:根接口。-Interceptor接口:扩展Advice,用于方法拦截。-MethodInterceptor:用于环绕通知。-其他特定通知接口:-MethodBeforeAdvice:前置通知。-AfterReturningAdvice:后置通知。-ThrowsAdvice:异常通知(引用中没有提到,但常见)。在回答中,我需要确保使用中文,结构清晰,并生成相关问题。最后添加引用标识。回答结构:1.**解释Advice接口**:简要介绍AdviceAOP中的作用。2.**继承结构**:描述接口层。-使用列表或清晰描述。-可能画图,但文本中要描述。3.**示例**:从引用[2]中提取代码示例。4.**引用**:在相关部分末尾添加引用标识。5.**生成相关问题**:在最后添加相关问题。确保LaTeX语法正确:如果有数学表达式,使用$...$或$$...$$,但在这个上下文中可能不需要,除非有公式。现在,构建回答:-开头:介绍SpringAOPAdvice。-主体:详细描述继承结构。-结尾:总结并生成问题。继承结构:-org.aopalliance.aop.Advice-org.springframework.aop.BeforeAdvice-org.springframework.aop.MethodBeforeAdvice-org.springframework.aop.AfterAdvice-org.springframework.aop.AfterReturningAdvice-org.springframework.aop.ThrowsAdvice(可选,引用中未提)-org.aopalliance.intercept.MethodInterceptor(实现环绕通知)在Spring中,MethodInterceptor不是直接扩展Advice,但它是一个子接口。参考Spring文档:-Advice是根。-BeforeAdvice,AfterAdvice等是子接口。-MethodBeforeAdviceextendsBeforeAdvice.-AfterReturningAdviceextendsAfterAdvice.-MethodInterceptorextendsInterceptor,whichextendsAdvice.在回答中描述。使用引用:-引用[2]中提到了MethodBeforeAdvice,AfterReturningAdvice,MethodInterceptor。-引用[3]关于切面优先级,但可能与继承结构无关。在描述中,在相关部分添加[^2]。生成相关问题:1.如何实现自定义Advice?2.Advice执行顺序如何控制?3.SpringAOP中的Advice类型有哪些?最后,确保回答真实可靠。</think>### Spring AOPAdvice接口的继承结构详解 在Spring AOP中,`Advice`接口是通知(Advice)的核心基础,它定义了在切入点(Pointcut)处执行的增强逻辑。通知类型包括前置通知(Before)、后置通知(After Returning)、环绕通知(Around)等。Spring的`Advice`继承结构基于AOP联盟(AOP Alliance)规范,并结合Spring的扩展实现。下面我将逐步解释其继承层和关键接口。 #### 1. **Advice接口的继承层** `Advice`接口的继承结构从顶层接口`org.aopalliance.aop.Advice`开始(来自AOP联盟),Spring在此基础上扩展了多个子接口和实现类。继承关系如下(使用树状结构描述): - **`org.aopalliance.aop.Advice`** 这是所有通知的根接口,标记性接口(无方法定义),仅表示一个增强逻辑单元[^2]。 - **`org.aopalliance.intercept.Interceptor`** 扩展自`Advice`,用于方法拦截的通用接口。核心子接口包括: - **`org.aopalliance.intercept.MethodInterceptor`** 实现环绕通知(Around Advice),提供`invoke(MethodInvocation invocation)`方法,允许在目标方法执行前后插入逻辑[^2]。 - 示例实现:`org.springframework.aop.framework.adapter.MethodInterceptor`(Spring适配器)。 - **`org.springframework.aop.BeforeAdvice`** Spring扩展的接口,表示前置通知的父接口。 - **`org.springframework.aop.MethodBeforeAdvice`** 定义`before(Method method, Object[] args, Object target)`方法,在目标方法执行前触发[^2]。 - **`org.springframework.aop.AfterAdvice`** Spring扩展的接口,表示后置通知的父接口。 - **`org.springframework.aop.AfterReturningAdvice`** 定义`afterReturning(Object result, Method method, Object[] args, Object target)`方法,在目标方法正常返回后触发[^2]。 - **`org.springframework.aop.ThrowsAdvice`** (引用中未直接提及,但常见)定义异常通知,通过`afterThrowing`方法处理目标方法抛出的异常。 #### 2. **关键接口的作用和示例** - **`MethodBeforeAdvice`**:用于前置通知,例如日志记录或权限检查。 - **`AfterReturningAdvice`**:用于后置通知,例如结果验证或资源清理。 - **`MethodInterceptor`**:用于环绕通知,功能最强大,可以控制整个方法执行流程(包括修改参数、返回值或阻止执行)。 引用[2]中的代码示例展示了如何实现多个通知接口: ```java public class LogAdvice implements MethodBeforeAdvice, AfterReturningAdvice, MethodInterceptor { @Override public void before(Method method, Object[] objects, Object target) throws Throwable { // 前置通知逻辑 } @Override public void afterReturning(Object result, Method method, Object[] objects, Object target) throws Throwable { // 后置通知逻辑 } @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { // 环绕通知:目标方法前执行 Object resultVal = methodInvocation.proceed(); // 调用目标方法 // 目标方法后执行 return resultVal; } } ``` 在此示例中,`LogAdvice`类同时实现了`MethodBeforeAdvice`、`AfterReturningAdvice`和`MethodInterceptor`,覆盖了主要通知类型[^2]。 #### 3. **继承结构的特点** - **灵活性**:开发者可以选择实现特定通知接口(如只实现`MethodBeforeAdvice`),或组合多个接口(如示例中的`LogAdvice`)。 - **执行顺序**:多个通知切入同一目标时,顺序由切面优先级控制(通过`@Order`注解),但接口本身不定义顺序逻辑[^3]。 - **AOP代理机制**:Spring AOP在运行时基于这些接口动态生成代理对象,将通知逻辑织入目标方法,遵循“代理对象的方法 = 增强处理 + 被代理对象的方法”原则[^2]。 #### 总结 Spring AOP的`Advice`继承结构以`org.aopalliance.aop.Advice`为根,通过Spring的扩展(如`BeforeAdvice`、`AfterAdvice`)和AOP联盟的`Interceptor`接口,支持多种通知类型。这种设计允许开发者灵活定义增强逻辑,并通过AOP代理实现非侵入式编程。在实际使用中,需结合切入点表达式(如引用[1]中提到的依赖配置)来定义织入点[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值