【问题标题】:Get method parameters with specific annotation in aspect in scala using java reflection使用java反射在scala中获取具有特定注释的方法参数
【发布时间】:2015-02-03 05:58:49
【问题描述】:

我在scala 中使用aspectj 中的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,现在可以获取注释。但是如何获取带有该注解的参数呢?

【问题讨论】:

  • 首先存在不一致,因为在问题代码中,该函数被命名为delete,但切入点在deleteEmployee附近。
  • @cchantep 抱歉,我的错误,复制粘贴时出现问题。我现在改了。但是,我仍然没有得到正确的名称和值。
  • 我建议尝试使用 vanilla Java 普通类,以检查问题是否与 Scala 代码有关。
  • @cchantep : 我的主要问题是我不知道如何根据注释获取参数名称和值
  • 我认为您无法获取名称或参数,只能获取参数列表及其在其中的位置。

标签: java scala reflection annotations aspectj


【解决方案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);
        }
    }
}

更新:

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

您还应该使用兼容 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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多