No se puede vincular un argumento en una posición arbitraria a través de args()
en AspectJ porque esto podría generar ambigüedad. Solo imagine que tiene dos o más parámetros del mismo tipo (o anotados por el mismo tipo de anotación en este caso). ¿Cuál de ellos debe estar vinculado al parámetro args()
nombrado? Así, mientras que
execution(public * *(.., @Deprecated (*), ..))
es posible como una expresión independiente (tenga en cuenta los paréntesis alrededor de la estrella), no es posible en combinación con args()
. Entonces, si no solo quiere interceptar la ejecución del método en sí, sino también encontrar el primero o todos los parámetros con la anotación dada, debe hacer exactamente lo que mostré en el otro artículo. Estoy un poco repitiendo, pero que así sea para que la respuesta no debe ser eliminada una vez más:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraint {}
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Application {
public void method1(@Constraint int i) {}
public void method2(String id, @Constraint float f) {}
public void method3(int i, @Constraint List<String> strings, @Constraint String s) {}
public void method4(int i, @Constraint Set<Integer> numbers, float f, boolean b) {}
public void method5(boolean b, String s, @Constraint String s2, float f, int i) {}
public void notIntercepted(boolean b, String s, String s2, float f, int i) {}
public static void main(String[] args) {
List<String> strings = new ArrayList<String>();
strings.add("foo");
strings.add("bar");
Set<Integer> numbers = new HashSet<Integer>();
numbers.add(11);
numbers.add(22);
numbers.add(33);
Application app = new Application();
app.method1(1);
app.method2("foo", 1f);
app.method3(1, strings, "foo");
app.method4(1, numbers, 1f, true);
app.method5(false, "foo", "bar", 1f, 1);
app.notIntercepted(false, "foo", "bar", 1f, 1);
}
}
import java.lang.annotation.Annotation;
import org.aspectj.lang.SoftException;
import org.aspectj.lang.reflect.MethodSignature;
public aspect ArgCatcherAspect {
before() : execution(public * *(.., @Constraint (*), ..)) {
System.out.println(thisJoinPointStaticPart);
MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature();
String methodName = signature.getMethod().getName();
Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
Annotation[][] annotations;
try {
annotations = thisJoinPoint.getTarget().getClass().
getMethod(methodName, parameterTypes).getParameterAnnotations();
} catch (Exception e) {
throw new SoftException(e);
}
int i = 0;
for (Object arg : thisJoinPoint.getArgs()) {
for (Annotation annotation : annotations[i]) {
if (annotation.annotationType() == Constraint.class)
System.out.println(" " + annotation + " -> " + arg);
}
i++;
}
}
}
Como se puede ver, es un poco más complicado de conseguir las anotaciones de una dado parámetro que solo su tipo declarado, pero básicamente funciona de la misma manera que en mi publicación anterior, es decir, al iterar sobre la lista de argumentos.
Sé que este es viejo, pero sigue sin aparecer como sin respuesta. ¿Podrías aceptar y votar mi respuesta si parece apropiado? Gracias. – kriegaex