简体   繁体   English

使用Java反射在Scala中获取具有方面特定注释的方法参数

[英]Get method parameters with specific annotation in aspect in scala using java reflection

I am using aop in scala using aspectj . 我正在使用aspectjscala使用aop。 I have a method 我有办法

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

How can I get the value of id in my aspect file. 如何获取我的外观文件中的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   
}

I am not able to get the values. 我无法获取这些值。

If I try 如果我尝试

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

It is always printing the size as 0. 始终将尺寸打印为0。

EDIT: Now I am getting the size correctly. 编辑:现在我正确获取大小。 The method was in object . 该方法是object But I think there are some problems with java reflection to read object . 但是我认为java反射来读取object存在一些问题。 I changed to class and now able to get the annotations. 我改为class ,现在可以获取注释。 But how can I get the parameter which is annotated with that annotation? 但是,如何获取带有该注释的参数?

Here is some Java sample code showing how to get method annotations and also parameter annotations along with paramater types (parameter names are unavailable as cchantep already mentioned). 这是一些Java示例代码,显示了如何获取方法注释以及参数注释以及参数类型(如已提及的cchantep,参数名称不可用)。 I guess you can easily convert it into Scala by yourself. 我想您可以轻松地将其自己转换为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);
        }
    }
}

Update: 更新:

Well, in Java 8 there is a way to determine parameter names if you compile your classes with the -parameters option. 好吧,在Java 8中,如果使用-parameters选项编译类,则可以确定参数名称 There is also a compiler switch in Eclipse for that if you use a Java 8 JRE/JDK: 如果您使用Java 8 JRE / JDK,则Eclipse中还有一个针对此的编译器开关:

Java 8的Eclipse编译器设置

You should also use a Java 8-compliant AspectJ version such as the current 1.8.5. 您还应该使用兼容Java 8的AspectJ版本,例如当前的1.8.5。 Then your aspect can look as follows: 那么您的方面可以如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM