2012-03-12 14 views
5

Ho bisogno di fare qualche elaborazione per determinare le dipendenze delle classi annotate JSR-330, usando la riflessione.Java: come verificare se un metodo è sovrascritto, utilizzando la riflessione

Sono perfettamente a conoscenza di tutti i contenitori IoC compatibili JSR-330, come Spring, Guice o PicoContainer. Tuttavia, ciò di cui ho bisogno non è risolvere e iniettare dipendenze, ma identificarle.

Ciò significa in sostanza che ho bisogno di implementare l'implementazione JSR-330, almeno quando si tratta di "parsing" di classe riflessiva.

C'è una parte della specifica JSR-330 che trovo leggermente fastidioso per implementare:

Un metodo annotato con @Inject che sostituisce un altro metodo annotato con @Inject verrà iniettato una sola volta per iniezione richiesta per istanza. Un metodo senza annotazione @Inject che esegue l'override di un metodo annotato con @Inject non verrà iniettato.

Ciò significa che le sottoclassi possono ridefinire il contratto di autowiring della loro classe di base, nonché agganciarsi al flusso di iniezione (attraverso il polimorfismo).

Ecco la mia domanda: Data una gerarchia di classi, esiste un modo semplice per verificare se un metodo in una parte della gerarchia viene sovrascritto più in basso nella gerarchia?

Il modo più semplice che vorrei fare questo nel mio caso è con la ricorsione dalla foglia della gerarchia:

private List<Method> getInjectableMethods(final Class<?> clazz) { 
    // recursive stop condition 
    if(clazz == null) { 
     return emptyList(); 
    } 

    // recursively get injectable methods from superclass 
    final List<Method> allInjectableMethods = newLinkedList(getInjectableMethods(clazz.getSuperclass())); 
    final List<Method> injectableMethods = newArrayList(); 

    // any overridden method will be present in the final list only if it is injectable in clazz 
    for (final Method method : clazz.getDeclaredMethods()) { 
     removeIf(allInjectableMethods, Methods.Predicates.overriddenBy(method)); 
     if (isInjectable(method)) { 
      injectableMethods.add(method); 
     } 
    } 
    allInjectableMethods.addAll(injectableMethods); 

    return allInjectableMethods; 
} 

Per quanto riguarda l'overriddenBy Guava-come predicato, vorrei verificare che:

  • I metodi che definiscono classi sono in una relazione isAssignableFrom
  • il nome metodi è la stessa
  • la metodi param formale gli eter sono uguali

La complessità risultante è O (n^2) in relazione al numero di metodi nella gerarchia.

Mi chiedevo se esistesse un modo più semplice o più efficiente per raggiungerlo, o qualsiasi libreria con tale funzionalità. Ho guardato senza successo sia in Guava che in Apache Commons ...

+0

Google Reflections forse? http://code.google.com/p/reflections/ – biziclop

+0

Ho guardato attraverso i javadocs e non ho trovato nulla per verificare l'override del metodo. Bella biblioteca, lo terrò a mente! – Eleaar

+0

Nel peggiore dei casi, renderà più semplice l'implementazione dell'algoritmo.:) – biziclop

risposta

1

Sfortunatamente, il grafico della classe è navigabile solo nella direzione della radice - quindi non c'è modo di trovare tutte le classi derivate eccetto controllare tutte le classi disponibili per alcuni programmi di caricamento classi. contenitori IoC non hanno questo problema, perché sanno sempre concreta attuazione (è parte della configurazione)

alberi di eredità sono di solito costruiti da IDE, ma AFAIUK usano Brite indicizzazione vigore su tutte le fonti/classi disponibili (si può esaminare le fonti di modifica della comunità di InteliiJ IDEA per gli indizi)

Problemi correlati