简体   繁体   中英

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

I am using aop in scala using aspectj . I have a method

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

How can I get the value of id in my aspect file.

@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.

EDIT: Now I am getting the size correctly. The method was in object . But I think there are some problems with java reflection to read object . I changed to class and now able to get the annotations. 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). I guess you can easily convert it into Scala by yourself.

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. There is also a compiler switch in Eclipse for that if you use a Java 8 JRE/JDK:

Java 8的Eclipse编译器设置

You should also use a Java 8-compliant AspectJ version such as the current 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);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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