2016-08-05 17 views
1

einen Punkt erstellt Schnitt Versuch, die von Annotation Parameter nehmen und dann kann es verwenden further.So Bis jetzt habe ich erreicht:Expression für Parametrisierte Anmerkung AspectJ

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

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

Bitte Beratung ..

Antwort

1

Es gibt mehrere Arten von Anmerkungen können Sie erfassen:

  • Klasse Anmerkungen
  • Methode Anmerkungen
  • Mitglied Annotationen
  • Methodenparameter Annotationen

Hier ist ein Beispiel für jeden:

Marker Anmerkung:

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(); 
} 

Treiberanwendung Annotationen an verschiedenen Orten verwendet:

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; 
    } 
} 

Aspect Erfassung Anmerkungen:

Die meisten der pointcut/Beratung Paare sind sehr elegant. Aber leider brauchen Sie eine ziemlich hässliche Reflexion, um an Parameter-Anmerkungen zu kommen.

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"); 
    } 
} 

Konsolenprotokoll:

Bitte beachten Sie, wie Anmerkungen an verschiedenen Orten zusammen mit ihren Parameterwerte protokolliert:

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

wow! schön! Vielen Dank! :) – xyz

+0

1 weitere Fragen: pointcut applyAspect (MyAnnotation myAnnotation): \t \t @ within (myAnnotation) && Ausführung (*. Neu (..)); wird dies für die Annotation über Klasse und Ausführung von Ameisen Konstruktor in der Klasse sein – xyz

+1

Sorry, ich war beschäftigt. Ja, deine Annahme ist richtig. In diesem Fall können Sie das neu erstellte Objekt über 'target()' holen, wenn Sie es protokollieren oder etwas anderes damit machen wollen. BTW, statt '* .new (..)' könntest du auch einfach 'new (..)' schreiben. – kriegaex