2010-11-05 7 views
30

Desidero ottenere un elenco completo di classi nell'applicazione annotate con l'annotazione @Custom. Qual è il miglior meccanismo per questa operazione?Come creare un elenco di classi annotate con la mia annotazione personalizzata?

ps. Ad esempio, in che modo le implementazioni JAX-RS trovano tutte le classi annotate con @Path? Mi piacerebbe usare lo stesso meccanismo.

+0

Si sta utilizzando un IDE? – thejh

+0

Vuoi cercare nel codice sorgente (.java) o nel codice compilato (.class)? –

+0

No, non uso alcun IDE. Mi interessa solo il codice compilato nel mio JAR. – yegor256

risposta

0

Esegui un ritrovamento nel vostro IDE della fonte, se si cerca di fare questo su classi compilate si avrebbe aggiungere un metodo per loro di sostenere questo, anche se decompilato le classi non credo annotazioni o commenti mostrerebbero su.

+1

Le annotazioni vengono visualizzate nel codice byte java –

+0

@Brian sì, se l'annotazione '@ Retention' è' RUNTIME' –

+0

... se sono definite con '@Retention (RUNTIME)' –

2

Come probabilmente saprete, Java non ha modo di enumerare tutti i pacchetti o le classi in ogni pacchetto. Quindi devi farlo nel modo "duro". Opzioni:

  1. Utilizzare uno strumento come grep per cercare l'annotazione. Vantaggio: veloce, semplice. Svantaggi: potrebbe restituire i falsi positivi (come le classi in cui l'annotazione è commentata).

  2. Compilare il codice ed elaborare il risultato con javap. Funziona a livello di bytecode [*]. Ti dà risultati accurati, ma l'output di javap non è pensato per l'elaborazione automatica.

  3. Utilizzare una libreria bytecode come ASM. Non per i deboli di cuore ma consente anche di accedere ad altri dati (come interfacce, campi, ecc.) In relazione all'annotazione.

  4. Ultima opzione: Eclipse utilizza un proprio compilatore Java che può creare un codice AST dal codice Java (anche se il codice non viene compilato). Vantaggio su ASM: ottieni un modello per il codice Java gratuitamente. Rende certe operazioni più semplici. Non è così facile da configurare, però. See my blog for an example.

[*]: L'annotazione deve avere Retention.RUNTIME affinché funzioni.

+0

Prima opzione = arggghh. Tutti gli altri: +1 –

+0

Quali delle opzioni che le implementazioni JAX-RS stanno utilizzando, ad esempio, per trovare tutte le classi annotate da '@ Path'? – yegor256

+0

Prestare la dovuta attenzione per affermare che non vi è alcun modo? Specialmente alla luce della biblioteca a cui mi sono collegato nella mia risposta? – meriton

0

Il modo più semplice sarebbe utilizzare un IDE as Jesus suggested.

Ma si potrebbe anche

Attenzione: tutti questi sono difficili. La soluzione AspectJ dovrebbe essere la più semplice.

3

Si dovrebbe dare un'occhiata a Scannotation.

+0

Sembra una buona opzione. Ci proverò più tardi – rpax

21

Di solito questo viene fatto utilizzando il processo chiamato scansione del percorso di classe. In generale i programmi di caricamento delle classi non consentono la scansione di tutte le classi sul classpath.Ma di solito l'unico caricatore di classe usato è UrlClassLoader da cui è possibile recuperare l'elenco di directory e file jar (vedere getURLs) e aprirli uno a uno per elencare le classi disponibili.

Questo approccio è implementato da librerie come Scannotation e Reflections.

Un altro approccio consiste nell'utilizzare Java Pluggable Annotation Processing API per scrivere un processore di annotazione che raccoglierà tutte le classi annotate in fase di compilazione e creerà il file di indice per l'utilizzo in runtime.

Il meccanismo di cui sopra è implementato nella libreria ClassIndex.

L'utilizzo della scansione del percorso di classe è in genere di due ordini di grandezza più lento dell'indicizzazione in fase di compilazione. Vedi this benchmark.

10

So che questa è una domanda vecchia, ma l'ho trovata nella mia ricerca per la scansione del percorso di classe e ho trovato un'altra buona risposta, quindi la aggiungo qui.

Google Guava ha un oggetto ClassPath che fornisce la scansione del percorso di classe "best effort" (che è tutto ciò che offre qualsiasi utilità di scansione classpath, in realtà). Poiché Guava è una libreria di utilità ampiamente adottata e mantenuta con cura, questa è una grande opzione per i progetti che (a) stanno già utilizzando Guava o (b) necessitano di una libreria stabile su cui poter fare affidamento per la scansione del classpath.

1

classindex è una libreria di scansione delle annotazioni in fase di compilazione, implementata utilizzando un processore di annotazione.

3

Si potrebbe provare la mia libreria FastClasspathScanner:

List<String> classNames = new FastClassPathScanner("com.mypackage") 
    .scan() 
    .getNamesOfClassesWithAnnotation(Custom.class); 
Problemi correlati