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