Spring Aop 5种通知写法及参数JoinPoint详解

Spring Aop切面参数JoinPoint详解

链接: 关于代理的一些基础知识(非必看).

Spring Aop5种代理通知的写法:

1.前置通知

@Before("method()")
    public void doBeforeAdvice(JoinPoint joinPoint){
        System.out.println("我是前置通知!!!");
    }

2.后置通知

    @After("method()")
    public void returnAfter(JoinPoint joinPoint){
        System.out.println("我是后置通知!!!");
    }

3.返回后通知

    @AfterReturning(value="method()",returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result){
        System.out.println("我是返回后通知!!!返回值是:"+result);
    }

4.异常通知

    @AfterThrowing(value = "method()",throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint,Exception ex){
        System.out.println("我是异常通知!!!异常是::"+ex);
    }

5.环绕通知

    @Around(value = "method()")
    public Object aroundLogging(ProceedingJoinPoint joinPoint){
        System.out.println("我是环绕通知");
        joinPoint.proceed();  //调用目标方法
 		System.out.println("我是环绕通知");
        return true;
    }

JoinPoint是什么:

JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的JoinPoint对象.
我们看看常用的几个方法:

public interface JoinPoint {

    Object getThis();

    Object getTarget();

    Object[] getArgs();

    Signature getSignature();

}
  1. getThis():获取当前对象(代理对象)
  2. getTarget():获取被代理对象
    由于AOP代理原理是直接添加字节码文件,不创建新的对象。所以getThis()和getTarget()获取到的是同一个对象。
  3. getArgs():获取被代理方法的参数,返回Object[]。
  4. getSignature():返回Signature 对象。

其他的一些api:

System.out.println("目标方法名为:" + joinPoint.getSignature().getName());
System.out.println("目标方法所属类的简单类名:" + joinPoint.getSignature().getDeclaringType().getSimpleName());
System.out.println("目标方法所属类的类名:" + joinPoint.getSignature().getDeclaringTypeName());
System.out.println("目标方法声明类型:" + Modifier.toString(joinPoint.getSignature().getModifiers()));

Signature 是什么:

Signature 封装了被代理方法的全部信息(方法命、注解),以及该方法所属类的信息。

在这里插入图片描述
可以看到,Signature 是一个父级接口,它有数十个实现类。我们这里模拟一下获取被代理方法的方法对象:

在这里插入图片描述
获取到了方法对象之后,我们就可以调用api,获取方法的所有信息,甚至可以调用.invoke()直接调用方法:
在这里插入图片描述

ProceedingJoinPoint是什么:

我们注意到,在环绕通知中,参数是ProceedingJoinPoint:

    @Around(value = "method()")
    public Object aroundLogging(ProceedingJoinPoint joinPoint){
        System.out.println("我是环绕通知");
        joinPoint.proceed();  //调用目标方法
 		System.out.println("我是环绕通知");
        return true;
    }

我们进去看看ProceedingJoinPoint 的源码:

在这里插入图片描述
我们发现ProceedingJoinPoint 是继承了JoinPoint,作为子接口(扩展了两个方法)。
为什么呢?因为ProceedingJoinPoint 是专为环绕通知服务的,既然是环绕通知,那么调用被代理方法的动作就必须我们手动触发了,所以ProceedingJoinPoint 增加了两个新的方法:

  1. proceed():调用被代理方法(无参)
  2. proceed(Object[] var1):调用被代理方法(有参)

好了 基本已经讲完,欢迎大家评论区指出不足,一起学习进步!

大家看完了点个赞,码字不容易啊。。。

  • 11
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易柏州Innovation

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值