Non è possibile associare un argomento in una posizione arbitraria tramite args()
in AspectJ perché ciò potrebbe causare ambiguità. Immagina di avere due o più parametri dello stesso tipo (o annotati dallo stesso tipo di annotazione in questo caso). Quale di questi deve essere associato al parametro args()
denominato? Così, mentre
execution(public * *(.., @Deprecated (*), ..))
è possibile come espressione autonoma (si prega di notare le parentesi intorno alla stella), non è possibile in combinazione con args()
. Quindi, se non vuoi solo intercettare l'esecuzione del metodo stesso, ma anche trovare il primo o tutti i parametri con l'annotazione specificata, devi fare esattamente quello che ho mostrato nell'altro articolo. Sto un pò mi ripeto, ma così sia in ordine per la risposta non da cancellare di nuovo:
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++;
}
}
}
Come si può vedere, si tratta di un po 'più complicato per ottenere le annotazioni di un dato parametro oltre al suo tipo dichiarato, ma fondamentalmente funziona allo stesso modo del mio post precedente, vale a dire iterando sull'elenco di argomenti.
So che questo è vecchio, ma ancora elencato come senza risposta. Vorresti accettare e revocare la mia risposta se mi sembra opportuno? Grazie. – kriegaex