Java 参数化注释AspectJ的表达式

Java 参数化注释AspectJ的表达式,java,aspectj,pointcut,Java,Aspectj,Pointcut,正在尝试创建一个从注释中获取参数的点切割,然后可以进一步使用它。到目前为止,我已达到: pointcut callDemoAspectPointCut(): call(Papa+.new()) && @within(MyAnnotation); //With param here after() returning(Object r) :callDemoAspectPointCut(){//use param here sysout("execut

正在尝试创建一个从注释中获取参数的点切割,然后可以进一步使用它。到目前为止,我已达到:

pointcut callDemoAspectPointCut():
      call(Papa+.new()) && @within(MyAnnotation); //With param here

   after() returning(Object r) :callDemoAspectPointCut(){//use param here
      sysout("executed");
}

请给出建议。

您可以捕获几种注释:

  • 类注释
  • 方法注释
  • 成员注释
  • 方法参数注释
以下是每种方法的示例:

标记注释:

package de.scrum\u master.app;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
@保留(RetentionPolicy.RUNTIME)
public@interface-MyAnnotation{
int id();
字符串名();
}
在不同位置使用注释的驱动程序应用程序:

package de.scrum\u master.app;
@MyAnnotation(id=1,name=“class”)
公共类应用程序{
@MyAnnotation(id=2,name=“member”)
私有字符串成员=“foo”;
@MyAnnotation(id=3,name=“method”)
公共静态void main(字符串[]args){
新应用程序().doSomething(“blah”,Math.PI);
}
私有字符串doSomething(字符串文本,@MyAnnotation(id=4,name=“parameter”)双倍数字){
字符串returnValue=成员+“”+数字;
成员=文本;
返回值;
}
}
方面捕获注释:

大多数切入点/建议对都非常优雅。但不幸的是,您需要一些相当丑陋的反射来获得参数注释

package de.scrum\u master.aspect;
导入java.lang.annotation.annotation;
导入java.lang.reflect.Method;
导入org.aspectj.lang.SoftException;
导入org.aspectj.lang.reflect.MethodSignature;
导入de.scrum_master.app.MyAnnotation;
公共方面注释参数方面{
切入点方法ExecutionInNotatedClass(MyAnnotation MyAnnotation):
@在(myAnnotation)和执行(**(..)中;
切入点annotatedMemberReadAccess(MyAnnotation MyAnnotation):
@注释(myAnnotation)和获取(**);
切入点annotatedMemberWriteAccess(MyAnnotation MyAnnotation):
@注释(myAnnotation)和集(**);
切入点注释方法索引(MyAnnotation MyAnnotation):
@注释(myAnnotation)和执行(**(..);
切入点注释的MethodParameter():
执行(**(..,@MyAnnotation(*),..);
在(MyAnnotation MyAnnotation)返回(对象返回值)之后:
MethodExecutionInNotatedClass(myAnnotation)
{
System.out.println(thisJoinPoint+“->”+返回值);
打印注释(myAnnotation);
}
在(MyAnnotation MyAnnotation)返回(对象返回值)之后:
annotatedMemberReadAccess(myAnnotation)
{
System.out.println(thisJoinPoint+“->”+返回值);
打印注释(myAnnotation);
}
之后(MyAnnotation MyAnnotation,Object newValue):
annotatedMemberWriteAccess(myAnnotation)和&args(newValue)
{
System.out.println(thisJoinPoint+“->”+新值);
打印注释(myAnnotation);
}
在(MyAnnotation MyAnnotation)返回(对象返回值)之后:
annotatedMethodExecution(myAnnotation)
{
System.out.println(thisJoinPoint+“->”+返回值);
打印注释(myAnnotation);
}
after():annotatedMethodParameter(){
System.out.println(此连接点);
MethodSignature MethodSignature=(MethodSignature)thisJoinPoint.getSignature();
类clazz=methodSignature.getDeclaringType();
试一试{
方法Method=clazz.getDeclaredMethod(methodSignature.getName(),methodSignature.getParameterTypes());
对于(注释[]parameterAnnotations:method.getParameterAnnotations()){
用于(注释:参数注释){
if(MyAnnotation的注释实例)
printAnnotation((MyAnnotation)注释);
}
}
}
捕获(NoSuchMethodException nsme){
抛出新的SoftException(nsme);
}
}
私有静态void printAnnotation(MyAnnotation MyAnnotation){
System.out.println(“+myAnnotation”);
System.out.println(“id=“+myAnnotation.id());
System.out.println(“name=“+myAnnotation.name()+”\n”);
}
}
控制台日志:

请注意如何记录不同位置的注释及其参数值:

set(String de.scrum\u master.app.Application.member)->foo
@de.scrum_master.app.MyAnnotation(id=2,name=member)
id=2
姓名=成员
get(String de.scrum\u master.app.Application.member)->foo
@de.scrum_master.app.MyAnnotation(id=2,name=member)
id=2
姓名=成员
set(String de.scrum_master.app.Application.member)->blah
@de.scrum_master.app.MyAnnotation(id=2,name=member)
id=2
姓名=成员
执行(String de.scrum_master.app.Application.doSomething(String,double))->foo 3.141592653589793
@de.scrum\u master.app.MyAnnotation(id=1,name=class)
id=1
名称=类
执行(String de.scrum_master.app.Application.doSomething(String,double))
@de.scrum_master.app.MyAnnotation(id=4,name=parameter)
id=4
名称=参数
执行(void de.scrum_master.app.Application.main(String[]))->null
@de.scrum\u master.app.MyAnnotation(id=1,name=class)
id=1
名称=类
执行(void de.scrum_master.app.Application.main(String[]))->null
@de.scrum_master.app.MyAnnotation(id=3,name=method)
id=3
名称=方法

1更多问题:切入点ApplySpect(MyAnnotation MyAnnotation):@内部(MyAnnotation)和执行(*.new(..);这将用于类上的注释和类中ant构造函数的执行对不起,我很忙。是的,你的假设是正确的。在这种情况下,如果需要,可以通过
target()
获取新创建的对象