使用java反射在scala中获取方面的特定注释的方法参数

时间:2015-02-03 05:58:49

标签: java scala reflection annotations aspectj

我使用scalaaspectj中使用了aop。我有一个方法

def delete(@Id id:Long, name:String)

如何在我的方面文件中获取id的值。

@Around("execution (* com.myapp.Employee.delete(..))")   
def message(joinPoint: ProceedingJoinPoint): Object = {    
  val methodSignature =joinPoint.getSignature.asInstanceOf[MethodSignature] 
  //get the value of the field id
  joinPoint.proceed   
}

我无法获得价值。

如果我尝试

val res = methodSignature.getMethod.getParameterAnnotations
res.map(annotations => println("size = "+annotations.length))

始终将尺寸打印为0.

编辑: 现在我正确地获得了大小。该方法位于object。但我认为java反射有一些问题需要阅读object。我改为class,现在能够获得注释。但是如何获得用该注释注释的参数?

1 个答案:

答案 0 :(得分:1)

以下是一些Java示例代码,演示了如何获取方法注释以及参数注释以及参数类型(参数名称不可用,因为 cchantep 已经提到过)。我想你可以自己轻松地将它转换成Scala。

package de.scrum_master.aspect;

import java.lang.annotation.Annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;

@Aspect
public class MyAspect {
    @Before("execution (* com.myapp.Employee.delete(..))")
    public void myAdvice(JoinPoint joinPoint) throws Throwable {
        System.out.println(joinPoint);
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getMethod().getName();
        Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();

        System.out.println("Method annotations:");
        Annotation[] methodAnnotations = joinPoint.getTarget().getClass().getMethod(methodName, parameterTypes).getAnnotations();
        for (Annotation annotation : methodAnnotations)
            System.out.println("  " + annotation);

        System.out.println("Parameter annotations:");
        Annotation[][] parameterAnnotations = joinPoint.getTarget().getClass().getMethod(methodName, parameterTypes).getParameterAnnotations();
        int parameterIndex = 0;
        for (Annotation[] annotationsPerParameter : parameterAnnotations) {
            System.out.println("  Parameter of type " + parameterTypes[parameterIndex++].getName() + ":");
            for (Annotation annotation : annotationsPerParameter)
                System.out.println("    " + annotation);
        }
    }
}

<强>更新

好吧,在Java 8中,如果使用-parameters选项编译类,则会有way to determine parameter names。如果您使用Java 8 JRE / JDK,那么Eclipse中还有一个编译器开关:

Eclipse compiler settings for Java 8

您还应该使用符合Java 8的AspectJ版本,例如当前的1.8.5版本。然后您的方面可以如下所示:

package de.scrum_master.aspect;

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

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;

@Aspect
public class MyAspect {
    @Before("execution(!static * *..Application.*(..))")
    public void myAdvice(JoinPoint joinPoint) throws Throwable {
        System.out.println(joinPoint);
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Parameter[] parameters = method.getParameters();

        System.out.println("Method annotations:");
        Annotation[] methodAnnotations = method.getAnnotations();
        for (Annotation annotation : methodAnnotations)
            System.out.println("  " + annotation);

        System.out.println("Parameter annotations:");
        for (Parameter parameter : parameters) {
            System.out.println("  " + parameter.getType().getName() + " " + parameter.getName());
            for (Annotation annotation : parameter.getAnnotations())
                System.out.println("    " + annotation);
        }
    }
}