代理的三种使用方法总结,带例子
1. 静态代理
2.动态jdk代理
3.spring注解代理
1.静态代理
接口类:
实现类:
代理类:
总结:注入对象,代理方法;缺点:接口的所有方法都需要写一遍,有多个方法时重复多;
2.Jdk代理
代理类:
用例:
总结:内部类实现方法实现,优点:可以指定实现特定方法;
3.spring注解代理
代理类:
4.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;
}
5. JoinPoint是什么:
JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的JoinPoint对象.
我们看看常用的几个方法:
public interface JoinPoint {
Object getThis();
Object getTarget();
Object[] getArgs();
Signature getSignature();
}
getThis():获取当前对象(代理对象)
getTarget():获取被代理对象
由于AOP代理原理是直接添加字节码文件,不创建新的对象。所以getThis()和getTarget()获取到的是同一个对象。
getArgs():获取被代理方法的参数,返回Object[]。
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()));
6. 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 增加了两个新的方法:
proceed():调用被代理方法(无参)
proceed(Object[] var1):调用被代理方法(有参)
参考:Spring Aop 5种通知写法及参数JoinPoint详解_joinpoint 添加参数_易柏州Innovation的博客-CSDN博客