2016-08-05 43 views
1

试图创建一个切入点内搭参数从注释,然后可以使用它further.So到目前为止,我已经达到:表达了参数化的注释AspectJ的

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

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

请咨询..

回答

1

有几种种注解,你可以捕捉:

  • 类注释
  • 方法的注释
  • 构件注解
  • 方法参数注释

下面是每个一个例子:

标记注释:使用注释在不同的地方

package de.scrum_master.app; 

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME) 
public @interface MyAnnotation { 
    int id(); 
    String name(); 
} 

驱动应用:

package de.scrum_master.app; 

@MyAnnotation(id = 1, name = "class") 
public class Application { 
    @MyAnnotation(id = 2, name = "member") 
    private String member = "foo"; 

    @MyAnnotation(id = 3, name = "method") 
    public static void main(String[] args) { 
     new Application().doSomething("blah", Math.PI); 
    } 

    private String doSomething(String text, @MyAnnotation(id = 4, name = "parameter") double number) { 
     String returnValue = member + " " + number; 
     member = text; 
     return returnValue; 
    } 
} 

看点捕捉注释:

大部分的切入点/建议对相当优雅。但不幸的是,你需要一些相当难看的反射来获取参数注释。

package de.scrum_master.aspect; 

import java.lang.annotation.Annotation; 
import java.lang.reflect.Method; 

import org.aspectj.lang.SoftException; 
import org.aspectj.lang.reflect.MethodSignature; 

import de.scrum_master.app.MyAnnotation; 

public aspect AnnotationParameterAspect { 
    pointcut methodExecutionInAnnotatedClass(MyAnnotation myAnnotation) : 
     @within(myAnnotation) && execution(* *(..)); 

    pointcut annotatedMemberReadAccess(MyAnnotation myAnnotation) : 
     @annotation(myAnnotation) && get(* *); 

    pointcut annotatedMemberWriteAccess(MyAnnotation myAnnotation) : 
     @annotation(myAnnotation) && set(* *); 

    pointcut annotatedMethodExecution(MyAnnotation myAnnotation) : 
     @annotation(myAnnotation) && execution(* *(..)); 

    pointcut annotatedMethodParameter() : 
     execution(* *(.., @MyAnnotation (*), ..)); 

    after(MyAnnotation myAnnotation) returning(Object returnValue) : 
     methodExecutionInAnnotatedClass(myAnnotation) 
    { 
     System.out.println(thisJoinPoint + " -> " + returnValue); 
     printAnnotation(myAnnotation); 
    } 

    after(MyAnnotation myAnnotation) returning(Object returnValue) : 
     annotatedMemberReadAccess(myAnnotation) 
    { 
     System.out.println(thisJoinPoint + " -> " + returnValue); 
     printAnnotation(myAnnotation); 
    } 

    after(MyAnnotation myAnnotation, Object newValue) : 
     annotatedMemberWriteAccess(myAnnotation) && args(newValue) 
    { 
     System.out.println(thisJoinPoint + " -> " + newValue); 
     printAnnotation(myAnnotation); 
    } 

    after(MyAnnotation myAnnotation) returning(Object returnValue) : 
     annotatedMethodExecution(myAnnotation) 
    { 
     System.out.println(thisJoinPoint + " -> " + returnValue); 
     printAnnotation(myAnnotation); 
    } 

    after() : annotatedMethodParameter() { 
     System.out.println(thisJoinPoint); 
     MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature(); 
     Class<?> clazz = methodSignature.getDeclaringType(); 
     try { 
      Method method = clazz.getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes()); 
      for (Annotation[] parameterAnnotations : method.getParameterAnnotations()) { 
       for (Annotation annotation : parameterAnnotations) { 
        if (annotation instanceof MyAnnotation) 
         printAnnotation((MyAnnotation) annotation); 
       } 
      } 
     } 
     catch (NoSuchMethodException nsme) { 
      throw new SoftException(nsme); 
     } 
    } 

    private static 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_master.app.Application.member) -> foo 
    @de.scrum_master.app.MyAnnotation(id=2, name=member) 
    id = 2 
    name = member 

get(String de.scrum_master.app.Application.member) -> foo 
    @de.scrum_master.app.MyAnnotation(id=2, name=member) 
    id = 2 
    name = member 

set(String de.scrum_master.app.Application.member) -> blah 
    @de.scrum_master.app.MyAnnotation(id=2, name=member) 
    id = 2 
    name = member 

execution(String de.scrum_master.app.Application.doSomething(String, double)) -> foo 3.141592653589793 
    @de.scrum_master.app.MyAnnotation(id=1, name=class) 
    id = 1 
    name = class 

execution(String de.scrum_master.app.Application.doSomething(String, double)) 
    @de.scrum_master.app.MyAnnotation(id=4, name=parameter) 
    id = 4 
    name = parameter 

execution(void de.scrum_master.app.Application.main(String[])) -> null 
    @de.scrum_master.app.MyAnnotation(id=1, name=class) 
    id = 1 
    name = class 

execution(void de.scrum_master.app.Application.main(String[])) -> null 
    @de.scrum_master.app.MyAnnotation(id=3, name=method) 
    id = 3 
    name = method 
+0

哇!美丽!谢谢! :) – xyz

+0

其他1个问题:pointcut applyAspect(MyAnnotation myAnnotation): \t \t @within(myAnnotation)&& execution(*。new(..));这将是类蚂蚁构造函数的类和执行的注解 – xyz

+1

对不起,我很忙。是的,你的假设是正确的。在这种情况下,如果你想记录它或者使用它来做其他事情,你可以通过'target()'获得新创建的对象。顺便说一句,而不是'* .new(..)',你也可以只写'new(..)'。 – kriegaex