7
votes

Spring AOP: Accédez aux noms d'arguments

J'utilise le printemps 3.x, Java 6.

J'ai un aspect @Arton avec le point de jointure suivant: xxx

donc, je suis fondamentalement Intéressé à intercepter tous les appels aux méthodes publiques de classes avec le nom de classe se terminant par "connecteur". Jusqu'à présent, si bon.

Maintenant, dans mon aspect, j'aimerais accéder aux noms d'arguments réels des méthodes: xxx

myarg < / strong> et autrearg

Je comprends qu'utiliser: xxx

fonctionnera réellement mais seulement si je compilise le code avec Le drapeau " -g " (débogage complet) et je préférerais ne pas le faire.

y a-t-il d'autre moyen d'avoir accès à ce type d'informations d'exécution.

merci L


0 commentaires

4 Réponses :


8
votes

Malheureusement, vous ne pouvez pas faire cela :-(. Il s'agit d'une limitation bien connue de JVM / Bytecode - Les noms d'arguments ne peuvent pas être obtenus à l'aide de la réflexion, car ils ne sont pas toujours stockés en bytecode (au contraire à la méthode / noms de classe).

En tant que solution de contournement Plusieurs cadres / spécifications introduisent des annotations personnalisées sur des arguments tels que webparam ( nom propriété) ou pathparam .

Pour le moment, tout ce que vous pouvez obtenir sans annotations est un éventail de valeurs.


4 commentaires

Je ne sais pas ici, mais je pense qu'il est vrai qu'ils ne peuvent pas être obtenus à l'aide de la réflexion pendant que ce n'est pas nécessairement vrai qu'ils ne sont pas stockés dans le bytecode. Comme mentionné dans la question, ils sont stockés lorsqu'ils sont compilés avec (au moins) javac -g: vars ... afin qu'ils puissent être affichés dans les débuggeurs. (Corrigez-moi si j'ai tort, s'il-vous plait)


Merci pour votre clarification, j'ai légèrement édité ma réponse originale.


Pouvez-vous expliquer plus en détail sur "PathParam" et "WebParam"?


Probablement en 2011, cette réponse a été correcte, mais puisque le commutateur -PARAMETERS Compiler a été introduit (également mentionné par @junkgui), vous pouvez a) compiler des informations de paramètre dans vos fichiers de classe et b) obtenir l'accès à cette information des versions actuelles de l'aspectj. Mais la question portait sur Java 6, donc pour cette version cette réponse est toujours correcte.



4
votes

Vérifiez les implémentations de org.springframework.core.parameNameDiscouverer .

Annotations comme @RequestParam utilisé par Spring inspectez le nom du paramètre si aucun net est défini. Donc, @RequestParam String FOO Fet Fetch le paramètre de demande nommé "FOO". Il utilise le mécanisme paramoreNameDiscouverer . Je ne suis tout simplement pas sûr de laquelle des implémentations sont utilisées, en essayez chacun d'eux.

Le localvariabletableParameNameNameDiscoverer lit le .Class et utilise ASM pour inspecter les noms.

Donc, c'est possible. Mais assurez-vous de mettre en cache cette information (par exemple - Stocker un nom de paramètre sur une carte, avec la clé = Méthode de classe + Index de paramètres).

Mais, comme cela est noté dans la documentation, vous avez besoin des informations de débogage. Du docs de @pathvariable :

La correspondance des noms de paramètres de méthode sur les noms de variable de modèle URI ne peut être effectué que si votre code est compilé avec le débogage activé. Si vous n'avez pas de débogage activé, vous devez spécifier le nom du nom de la variable de modèle URI dans l'annotation @pathvaitaiable afin de lier la valeur résolue du nom de la variable sur un paramètre de méthode

Donc, si vous ne voulez vraiment pas inclure cette information, la réponse de Tomasz Nurkiewicz explique la solution de contournement.


2 commentaires

Merci Bozhidar, le Javadoc pour le localvariabletableParameNameNameDiscoverer dit: renvoie * null si le fichier de classe a été compilé sans informations de débogage


@LUCIANO FIANDESIO OUI, VRAI. Je vais mettre à jour pour inclure un peu plus d'informations



3
votes

Dans Java 8 Il existe un nouveau drapeau du compilateur qui permet de stocker des métadonnées supplémentaires avec code octet et ces noms de paramètres peuvent être extraits à l'aide de l'objet Paramètre dans la réflexion. Voir Spécification JDK 8 . Dans les versions plus récentes de Hibernate org.springframework.core.ParameNameDiscoverer utilise cette fonctionnalité. Pour l'utiliser, compilez-le en utilisant javac avec cet indicateur: xxx

paramètres d'accès à l'aide de la réflexion paramètre classe.


0 commentaires

1
votes

Je ne suis pas sûr de ne pas être un meilleur moyen, mais j'ai ajouté une annotation sur ma méthode:

Mon annotation: p> xxx pré>

et dans l'aspect: P>

@Around("aspect param && @annotation(readApi)")
public Object logParams(ProceedingJoinPoint pjp,
        ReadApi readApi) 
{
    //use pjp.getArgs() and readApi.paramNames();
}


0 commentaires