问题
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?
回答1:
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:
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);
}
}
}
来源:https://stackoverflow.com/questions/28292310/get-method-parameters-with-specific-annotation-in-aspect-in-scala-using-java-ref