参数化注释AspectJ的表达式

时间:2016-08-05 06:58:57

标签: java aspectj pointcut

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

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

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

请建议..

1 个答案:

答案 0 :(得分:1)

您可以捕获几种注释:

  • class annotations
  • 方法注释
  • 会员注释
  • 方法参数注释

以下是每个例子:

标记注释:

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