前置通知(Before Advice)
前置通知在目标方法执行之前被调用,常用于执行一些预处理逻辑,例如权限验证、参数校验等。在 Spring 配置文件中,前置通知通过<aop:before>
标签进行配置,以下是一个典型的示例:
<aop:before method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>
上述配置中,method="yanzheng"
指定了通知方法,即当满足pointcut
定义的切入点条件时,会执行yanzheng
方法。pointcut
属性用于定义切入点表达式,execution(public void com.qcby.Demo.search(..))
表示当com.qcby.Demo
类中的search
方法被调用时,触发前置通知。
最终通知(After Advice)
最终通知在目标方法执行之后被调用,无论目标方法是正常返回还是抛出异常,该通知都会执行。这种通知类型适用于资源清理、状态更新等场景。在 Spring 配置文件中,通过<aop:after>
标签配置最终通知:
<aop:after method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>
即使search
方法执行过程中出现异常,yanzheng
方法也会被执行,确保后续的清理或记录操作能
够顺利完成。
异常通知(After-Throwing Advice)
异常通知仅在目标方法抛出异常时被调用,它允许我们在异常发生时进行特定的处理,如记录异常日志、回滚事务等。通过<aop:after-throwing>
标签配置异常通知:
<aop:after-throwing method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>
当search
方法抛出异常,yanzheng
方法会捕获异常并执行相应的处理逻辑,帮助开发者更好地管理程序运行过程中的错误情况。
后置通知(After-Returning Advice)
后置通知在目标方法正常执行完毕且返回结果后被调用,可用于记录方法执行结果、更新缓存等操作。通过<aop:after-returning>
标签配置后置通知:
<aop:after-returning method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>
只有search
方法成功执行并返回,yanzheng
方法才会被触发,如果方法执行过程中抛出异常,后置通知不会执行。
环绕通知(Around Advice)
环绕通知是功能最强大的通知类型,它可以在目标方法执行之前和之后都执行自定义逻辑,甚至可以决定是否执行目标方法。环绕通知通过<aop:around>
标签进行配置:
<aop:around method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>
在环绕通知的方法中,开发者可以使用ProceedingJoinPoint
参数来调用目标方法,实现更加灵活的逻辑控制。例如,在性能监控场景中,可以在目标方法执行前记录开始时间,执行后记录结束时间并计算执行耗时。
package com.qcby;import org.aspectj.lang.ProceedingJoinPoint;public class DemoProxy {public void yanzheng(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("对name和age进行验证.....执行之前");
// 执行切入点proceedingJoinPoint.proceed();System.out.println("对name和age进行验证.....执行之后");}}
注解式 AOP 基础配置
要使用注解方式配置 AOP,首先需要确保以下几点:
- 在 Spring 配置文件中启用 AOP 自动代理:
<aop:aspectj-autoproxy/>
- 创建切面类并使用
@Aspect
注解标记 - 将切面类声明为 Spring Bean(使用
@Component
、@Controller
等注解)
下面是一个典型的注解式切面类示例:
package com.qcby;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Controller;@Controller
@Aspect
public class DemoProxy {// 通知方法实现
}
各种通知类型的注解实现
环绕通知(@Around)
环绕通知是功能最强大的通知类型,它允许在目标方法执行前后都添加自定义逻辑。在DemoProxy
类中,环绕通知的实现如下:
@Around(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("对name和age进行验证.....执行之前");// 调用目标方法proceedingJoinPoint.proceed();System.out.println("对name和age进行验证.....执行之后");
}
关键点解析:
@Around
注解指定了通知类型和切入点表达式ProceedingJoinPoint
参数用于控制目标方法的执行proceed()
方法调用目标方法,可以在调用前后添加自定义逻辑
前置通知(@Before)
前置通知在目标方法执行前被调用:
@Before(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng() {System.out.println("对name和age进行验证!!");
}
后置通知(@After)
后置通知在目标方法执行后被调用,无论方法是否抛出异常:
@After(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng() {System.out.println("后置通知执行");
}
异常通知(@AfterThrowing)
异常通知仅在目标方法抛出异常时被调用:
@AfterThrowing(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng() {System.out.println("异常通知执行");
}
//在查询之前验证name和agepublic void search(String name,int age){Integer a=10/0;System.out.println("search.................");}}
返回通知(@AfterReturning)
返回通知在目标方法正常返回后被调用:
@AfterReturning(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng() {System.out.println("返回通知执行");
}
注解式 AOP 的优势
与 XML 配置方式相比,注解式 AOP 具有以下优势:
- 代码更简洁:无需编写大量 XML 配置,所有 AOP 逻辑集中在切面类中
- 可读性更强:通知类型和切入点表达式直接与通知方法关联
- 维护更方便:AOP 逻辑与切面类代码放在一起,便于修改和管理
- 类型安全:编译时就能检查切入点表达式的正确性