Обновлен:
ОК, лучшая ссылка, которую я мог найти, находится на этой странице: Аннотации, Pointcuts and Advice .
Вы можете сопоставить метод, однако вы не сможете поймать параметр (только метод и аннотацию). Так что вам нужно сделать сочетание сочетания точек и отражения. Примерно так:
@Pointcut(
"execution(@com.xxx.xxx.annotation.MyAnnotationForMethod * *(.., @com.xxx.xxx.annotation.MyAnnotationForParam (*), ..))")
public void annotatedMethod(){}
@Before("annotatedMethod()")
public void doStuffOnParam(final JoinPoint jp){
final Signature signature = jp.getSignature();
if(signature instanceof MethodSignature){
final MethodSignature ms = (MethodSignature) signature;
final Method method = ms.getMethod();
final String[] parameterNames = ms.getParameterNames();
final Class<?>[] parameterTypes = ms.getParameterTypes();
final Annotation[][] parameterAnnotations =
method.getParameterAnnotations();
for(int i = 0; i < parameterAnnotations.length; i++){
final Annotation[] annotations = parameterAnnotations[i];
final MyAnnotationForParam paramAnnotation =
getAnnotationByType(annotations, MyAnnotationForParam.class);
if(paramAnnotation != null){
this.processParameter(ms.toShortString(),
parameterNames[i],
parameterTypes[i],
paramAnnotation);
}
}
}
}
/**
* In an array of annotations, find the annotation of the specified type, if any.
* @return the annotation if available, or null
*/
@SuppressWarnings("unchecked")
private static <T extends Annotation> T getAnnotationByType(final Annotation[] annotations,
final Class<T> clazz){
T result = null;
for(final Annotation annotation : annotations){
if(clazz.isAssignableFrom(annotation.getClass())){
result = (T) annotation;
break;
}
}
return result;
}
/**
* Do some processing based on what we found.
* @param signature method signature
* @param paramName parameter name
* @param paramType parameter type
* @param paramAnnotation annotation we found
*/
private void processParameter(final String signature,
final String paramName,
final Class<?> paramType,
final MyAnnotationForParam paramAnnotation){
System.out.println(MessageFormat.format(
"Found parameter ''{0}'' \n of type ''{1}'' \n with annotation ''{2}'' \n in method ''{3}''",
paramName,
paramType,
paramAnnotation,
signature));
}
Вот мой тестовый класс для вышеуказанного аспекта:
public class TestClass{
@MyAnnotationForMethod
public void simpleTestMethod(@MyAnnotationForParam final String param1){
System.out.println("Method body (simple)");
};
@MyAnnotationForMethod
public void complexTestMethod(final String param1,
@MyAnnotationForParam final Float param2,
@MyAnnotationForParam final Boolean param3){
System.out.println("Method body (complex)");
};
public static void main(final String[] args){
System.out.println("Starting up");
final TestClass testObject = new TestClass();
testObject.simpleTestMethod("Hey");
testObject.complexTestMethod("Hey", 123.4f, false);
System.out.println("Finished");
}
}
и вот вывод:
Starting up
Found parameter 'param1'
of type 'class java.lang.String'
with annotation '@com.xxx.xxx.annotation.MyAnnotationForParam()'
in method 'TestClass.simpleTestMethod(..)'
Method body (simple)
Found parameter 'param2'
of type 'class java.lang.Float'
with annotation '@com.xxx.xxx.annotation.MyAnnotationForParam()'
in method 'TestClass.complexTestMethod(..)'
Found parameter 'param3'
of type 'class java.lang.Boolean'
with annotation '@com.xxx.xxx.annotation.MyAnnotationForParam()'
in method 'TestClass.complexTestMethod(..)'
Method body (complex)
Finished
Подсказка
Возможно, вы захотите многое из этого кэшировать, нет необходимости анализировать каждый параметр каждой аннотации при каждом выполнении. Сохраните карту, для которой параметр какого метода несет аннотацию, и обработайте только эти параметры.