aspect学习(2)target&thisJoinPoint
程序员文章站
2022-04-28 18:57:41
...
需求三 在需求一的基础上增加,当调用setX,setY,setZ方法时,打印属性x,y,z改变前后的。 想要知道x,y,z改变前的,那么在LogAspect.aj中必须要能拿到目标对象的实例、当前调用的是目标对象中的哪个方法(为什么只需知道这2个东东就可以了呢?大家可以先想想。
需求三
在需求一的基础上增加,当调用setX,setY,setZ方法时,打印属性x,y,z改变前后的值。
想要知道x,y,z改变前的值,那么在LogAspect.aj中必须要能拿到目标对象的实例、当前调用的是目标对象中的哪个方法(为什么只需知道这2个东东就可以了呢?大家可以先想想。。。。)
那么该怎样拿到目标对象实例呢?看代码
LogAspect.aj的代码
package com.fei.aspect; import org.aspectj.lang.Signature; import com.fei.bean.Point; public aspect LogAspect { public pointcut printLog(Object p): call( void Point.set*(int)) && target(p); void around(Object p):printLog(p){ System.out.println(p); System.out.println(thisJoinPoint.getTarget()); System.out.println(thisJoinPoint.getKind()); for(Object o : thisJoinPoint.getArgs()) System.out.println(o); System.out.println( "signature========"); Signature signature = thisJoinPoint.getSignature(); System.out.println(signature.getClass()); System.out.println(signature.getName()); System.out.println(signature.getDeclaringTypeName()); System.out.println(signature.getModifiers()); System.out.println(signature.toLongString()); } }
MainTest.java源码及运行结果截图
通过上面源码及结果我们知道,要想拿到目标对象实例,有2中途径,一是在 pointcut中用target,二是直接用thisJoinPoint.getTarget()拿到,方法名可用signature.getName()拿到。
好了,我们需要的东东可以拿到了,下面源码来实现需求。
package com.fei.aspect; import java.lang.reflect.Method; import org.aspectj.lang.Signature; import com.fei.bean.Point; public aspect LogAspect { public pointcut printLog(): call( void Point.set*(int)); void around():printLog(){ Object o = thisJoinPoint.getTarget(); Signature signature = thisJoinPoint.getSignature(); String methodName = signature.getName(); // System.out.println("在调用"+signature.getDeclaringTypeName()+"."+signature.getName()); System.out.println("在调用"+signature.toLongString()); //通过反射拿值 System.out.println("属性改变前:" + getXXX(o,methodName)); proceed(); //通过反射拿值 System.out.println("属性改变后:" + getXXX(o,methodName)); } private Object getXXX(Object o, String methodName){ Object value = null; try { Method m = o.getClass().getMethod(methodName.replace("set", "get"), null); value = m.invoke(o, null); } catch (Exception e) { e.printStackTrace(); } return value; } }
上一篇: Python中利用函数装饰器实现备忘功能