web-dev-qa-db-fra.com

Comment construire une liste de classes annotées avec mon annotation personnalisée?

Je veux obtenir une liste complète des classes dans l'application qui sont annotées avec @Custom annotation. Quel est le meilleur mécanisme pour cette opération?

ps. Par exemple, comment les implémentations JAX-RS trouvent toutes les classes annotées avec @Path? Je voudrais utiliser le même mécanisme.

34
yegor256

Habituellement, cela se fait à l'aide du processus appelé analyse du chemin de classe. En général, les chargeurs de classe ne permettent pas de parcourir toutes les classes sur le chemin de classe. Mais généralement, le seul chargeur de classe utilisé est UrlClassLoader à partir duquel nous pouvons récupérer la liste des répertoires et des fichiers jar (voir getURLs ) et les ouvrir un par un pour répertorier les classes disponibles.

Cette approche est implémentée par des bibliothèques comme Scannotation et Reflections .

Une autre approche consiste à utiliser Java Pluggable Annotation Processing API pour écrire un processeur d'annotations qui collectera toutes les classes annotées au moment de la compilation et construira le fichier d'index pour une utilisation au moment de l'exécution.

Le mécanisme ci-dessus est implémenté dans la bibliothèque ClassIndex .

L'utilisation de l'analyse du chemin de classe est généralement plus lente de deux ordres de grandeur que l'indexation au moment de la compilation. Voir cette référence .

24
Sławek

Je sais que c'est une vieille question, mais je l'ai rencontrée dans ma propre recherche d'analyse de chemin de classe et j'ai trouvé une autre bonne réponse, donc je l'ajoute ici.

Google Guava a un objet ClassPath qui fournit une analyse de chemin de classe "au mieux" (ce qui est vraiment tout l'utilitaire d'analyse de chemin de classe). Étant donné que Guava est une bibliothèque d'utilitaires largement adoptée et soigneusement entretenue, c'est une excellente option pour les projets qui (a) utilisent déjà Guava, ou (b) ont besoin d'une bibliothèque stable sur laquelle ils peuvent s'appuyer pour l'analyse des chemins de classe.

11
sigpwned

Vous devriez jeter un œil à Scannotation .

3
keuleJ

classindex est une bibliothèque d'analyse d'annotation au moment de la compilation, implémentée à l'aide d'un processeur d'annotation.

3
snorbi

Vous pouvez essayer ma bibliothèque FastClasspathScanner :

List<String> classNames = new FastClassPathScanner("com.mypackage")
    .scan()
    .getNamesOfClassesWithAnnotation(Custom.class);
3
Luke Hutchison

Comme vous le savez probablement déjà, Java n'a aucun moyen d'énumérer tous les packages ou les classes de chaque package. Vous devez donc le faire de la manière "difficile". Options:

  1. Utilisez un outil comme grep pour rechercher l'annotation. Avantage: rapide, simple. Inconvénients: peut renvoyer des faux positifs (comme les classes où l'annotation est commentée).

  2. Compilez le code et traitez le résultat avec javap. Cela fonctionne au niveau du bytecode [*]. Il vous donne des résultats précis mais la sortie de javap n'est pas vraiment destinée au traitement automatique.

  3. Utilisez une bibliothèque de bytecode comme ASM . Pas pour les âmes sensibles, mais cela vous permet également d'accéder à d'autres données (comme les interfaces implémentées, les champs, etc.) en relation avec l'annotation.

  4. Dernière option: Eclipse utilise son propre compilateur Java qui peut construire un code AST from Java code (même si le code ne 't compile). Avantage sur ASM: Vous obtenez un modèle pour Java code gratuit. Rend certaines opérations plus simples. Pas si facile à configurer, cependant. Voir mon blog pour un exemple .

[*]: L'annotation doit avoir Retention.RUNTIME pour que cela fonctionne.

2
Aaron Digulla

Exécutez une recherche dans votre IDE sur la source, si vous essayez de le faire sur des classes compilées, vous auriez dû leur ajouter une méthode pour le supporter, même si vous avez décompilé les classes, je ne pense pas des annotations ou des commentaires apparaissent.

0
Keibosh

Le moyen le plus simple serait d'utiliser un IDE comme l'a suggéré Jésus .

Mais vous pourriez aussi

Attention: tout cela est délicat. La solution AspectJ devrait être la plus simple.

0