ProceedingJoinPoint获取当前方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ProceedingJoinPoint获取当前⽅法
aspectJ切⾯通过ProceedingJoinPoint想要获取当前执⾏的⽅法:
错误⽅法:
Signature s = pjp.getSignature();
MethodSignature ms = (MethodSignature)s;
Method m = ms.getMethod();
这种⽅式获取到的⽅法是接⼝的⽅法⽽不是具体的实现类的⽅法,因此是错误的。
正确⽅法:
Signature sig = pjp.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能⽤于⽅法");
}
msig = (MethodSignature) sig;
Object target = pjp.getTarget();
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
AspectJ使⽤ng.JoinPoint接⼝表⽰⽬标类连接点对象,如果是环绕增强时,使⽤ng.ProceedingJoinPoint表⽰连接点对象,该类是JoinPoint的⼦接⼝。
任何⼀个增强⽅法都可以通过将第⼀个⼊参声明为JoinPoint访问到连接点上下⽂的信息。
我们先来了解⼀下这两个接⼝的主要⽅法:
1)JoinPoint
ng.Object[] getArgs():获取连接点⽅法运⾏时的⼊参列表;
Signature getSignature() :获取连接点的⽅法签名对象;
ng.Object getTarget() :获取连接点所在的⽬标对象;
ng.Object getThis() :获取代理对象本⾝;
2)ProceedingJoinPoint
ProceedingJoinPoint继承JoinPoint⼦接⼝,它新增了两个⽤于执⾏连接点⽅法的⽅法:
ng.Object proceed() throws ng.Throwable:通过反射执⾏⽬标对象的连接点处的⽅法;
ng.Object proceed(ng.Object[] args) throws ng.Throwable:通过反射执⾏⽬标对象连接点处的⽅法,不过使⽤新的⼊参替换原来的⼊参。
JoinPoint 对象
JoinPoint对象封装了SpringAop中切⾯⽅法的信息,在切⾯⽅法中添加JoinPoint参数,就可以获取到封装了该⽅法信息的JoinPoint对象.
常⽤api:
⽅法名功能
Signature getSignature();获取封装了署名信息的对象,在该对象中可以获取到⽬标⽅法名,所属类的Class等信息
Object[] getArgs();获取传⼊⽬标⽅法的参数对象
Object getTarget();获取被代理的对象
Object getThis();获取代理对象
ProceedingJoinPoint对象
ProceedingJoinPoint对象是JoinPoint的⼦接⼝,该对象只⽤在@Around的切⾯⽅法中,
添加了
Object proceed() throws Throwable //执⾏⽬标⽅法
Object proceed(Object[] var1) throws Throwable //传⼊的新的参数去执⾏⽬标⽅法
两个⽅法.
Demo
切⾯类
@Aspect
@Component
public class aopAspect {
/**
* 定义⼀个切⼊点表达式,⽤来确定哪些类需要代理
* execution(* aopdemo.*.*(..))代表aopdemo包下所有类的所有⽅法都会被代理
*/
@Pointcut("execution(* aopdemo.*.*(..))")
public void declareJoinPointerExpression() {}
/**
* 前置⽅法,在⽬标⽅法执⾏前执⾏
* @param joinPoint 封装了代理⽅法信息的对象,若⽤不到则可以忽略不写
*/
@Before("declareJoinPointerExpression()")
public void beforeMethod(JoinPoint joinPoint){
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()));
//获取传⼊⽬标⽅法的参数
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
System.out.println("第" + (i+1) + "个参数为:" + args[i]);
}
System.out.println("被代理的对象:" + joinPoint.getTarget());
System.out.println("代理对象⾃⼰:" + joinPoint.getThis());
}
/**
* 环绕⽅法,可⾃定义⽬标⽅法执⾏的时机
* @param pjd JoinPoint的⼦接⼝,添加了
* Object proceed() throws Throwable 执⾏⽬标⽅法
* Object proceed(Object[] var1) throws Throwable 传⼊的新的参数去执⾏⽬标⽅法
* 两个⽅法
* @return此⽅法需要返回值,返回值视为⽬标⽅法的返回值
*/
@Around("declareJoinPointerExpression()")
public Object aroundMethod(ProceedingJoinPoint pjd){
Object result = null;
try {
//前置通知
System.out.println("⽬标⽅法执⾏前...");
//执⾏⽬标⽅法
//result = pjd.proeed();
//⽤新的参数值执⾏⽬标⽅法
result = pjd.proceed(new Object[]{"newSpring","newAop"});
//返回通知
System.out.println("⽬标⽅法返回结果后...");
} catch (Throwable e) {
//异常通知
System.out.println("执⾏⽬标⽅法异常后...");
throw new RuntimeException(e);
}
//后置通知
System.out.println("⽬标⽅法执⾏后...");
return result;
}
}
被代理类
/**
* 被代理对象
*/
@Component
public class TargetClass {
/**
* 拼接两个字符串
*/
public String joint(String str1, String str2) {
return str1 + "+" + str2;
}
}
测试类
public class TestAop {
@Test
public void testAOP() {
//1、创建Spring的IOC的容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:bean.xml");
//2、从IOC容器中获取bean的实例
TargetClass targetClass = (TargetClass) ctx.getBean("targetClass");
//3、使⽤bean
String result = targetClass.joint("spring","aop");
System.out.println("result:" + result);
}
}
输出结果
⽬标⽅法执⾏前...
⽬标⽅法名为:joint
⽬标⽅法所属类的简单类名:TargetClass
⽬标⽅法所属类的类名:aopdemo.TargetClass
⽬标⽅法声明类型:public
第1个参数为:newSpring
第2个参数为:newAop
被代理的对象:aopdemo.TargetClass@4efc180e
代理对象⾃⼰:aopdemo.TargetClass@4efc180e
⽬标⽅法返回结果后...
⽬标⽅法执⾏后...
result:newSpring+newAop。