Spring通知(前置通知,后置通知,返回通知,异常通知,环绕通知)

本文详细介绍了面向切面编程(AOP)中的五种主要通知类型:前置通知、后置通知、返回通知、异常通知和环绕通知。每种通知类型都通过实例展示了其特点和应用场景,帮助读者更好地理解和掌握AOP在实际开发中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前置通知
--前置通知:在方法执行之前执行的通知
--前置通知使用 @Before 注解, 并将切入点表达式的值作为注解值。
/**
 * 声明该方法是一个前置通知:在目标方法开始之前执行
 */
@Before("execution(public int aop.AtithmeticCalculatorImpl.*(int,int))")
public void beforeMethod(JoinPoint joinPoint){
    System.out.println("调用"+joinPoint.getSignature().getName()+"方法,处理"Arrays.asList(joinPoint.getArgs()));
}

二、后置通知
-- 后置通知是在连接点完成之后执行的, 即连接点返回结果或者抛出异常的时候, 下面的后置通知记录了方法的终止
/**
 * 在目标方法执行后(无论是否发生异常),执行的通知
 * 在后置通知中无法访问目标执行的结果
 */
@After("execution(public int aop.AtithmeticCalculatorImpl.*(int,int))")
public void afterMethod(JoinPoint joinPoint){
    System.out.println("调用"+joinPoint.getSignature().getName()+"方法结束");
}

三、返回通知
--在返回通知中, 只要将 returning属性添加到 @AfterReturning注解中, 就可以访问连接点的返回值. 该属性的值即为用来传入返回值的参数名称.
--必须在通知方法的签名中添加一个同名参数. 在运行时, Spring AOP 会通过这个参数传递返回值.
--原始的切点表达式需要出现在 pointcut 属性中
/**
 * 在方法正常结束的时候执行
 * 返回通知可以获取目标方法的返回值
 */
@AfterReturning(value "execution(public int aop.AtithmeticCalculatorImpl.*(int,int))"returning "result")
public void afterReturningMethod(JoinPoint joinPoint,Override result){
    System.out.println("处理结果为:"+result.toString());
}

四、异常通知
--只在连接点抛出异常时才执行异常通知
--将 throwing 属性添加到 @AfterThrowing 注解中, 也可以访问连接点抛出的异常. Throwable是所有错误和异常类的超类. 所以在异常通知方法可以捕获到任何错误和异常.
--如果只对某种特殊的异常类型感兴趣, 可以将参数声明为其他异常的参数类型. 然后通知就只在抛出这个类型及其子类的异常时才被执行.
/**
 * 在目标方法出现异常时执行
 * 可以访问到方法的异常对象,且可以指定在出现特定异常时在执行通知代码
 */
@AfterThrowing(value "execution(public int aop.AtithmeticCalculatorImpl.*(int,int))",throwing "e")
public void afterThrowingMethod(JoinPoint joinPoint,Exception e){
    System.out.println(joinPoint.getSignature().getName()+"发生异常:"+e);
}

五、环绕通知
--环绕通知是所有通知类型中功能最为强大的, 能够全面地控制连接点. 甚至可以控制是否执行连接点.
--对于环绕通知来说, 连接点的参数类型必须是 ProceedingJoinPoint. 它是 JoinPoint的子接口, 允许控制何时执行, 是否执行连接点.
--在环绕通知中需要明确调用 ProceedingJoinPoint 的 proceed() 方法来执行被代理的方法. 如果忘记这样做就会导致通知被执行了, 但目标方法没有被执行.
--注意: 环绕通知的方法需要返回目标方法执行之后的结果, 即调用 joinPoint.proceed(); 的返回值, 否则会出现空指针异常
/**
 * 环绕方法需要携带ProceedingJoinPoint类型的参数
 * 环绕通知类似于动态代理的过程,ProceedingJoinPoint类型的参数可以决定是否执行目标方法
 * 且环绕通知必须有返回值,返回值为目标方法的返回值
 */
@Around("execution(public int aop.AtithmeticCalculatorImpl.*(int,int))")
public Object aroundMethod(ProceedingJoinPoint pjp){
    Object obj=null;
    try {
        //前置通知
        System.out.println("调用"+pjp.getSignature().getName()+"方法,处理"Arrays.asList(pjp.getArgs()));
        //执行方法
        obj=pjp.proceed();
        //返回通知
        System.out.println("处理结果为:"+obj);
    catch (Throwable e) {
        //异常通知
        System.out.println(pjp.getSignature().getName()+"发生异常:"+e);
        //抛出异常
        throw new RuntimeException(e);
    }
    //后置通知
    System.out.println("调用"+pjp.getSignature().getName()+"方法结束");
    return obj;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值