2012-02-24 7 views
23

Nel mio progetto, sto cercando di migrare tutti gli usi diPrimavera cablaggio per tipo è più lento da grandezza di cablaggio per nome

Foo foo = (Foo) beanFactory.getBean("name"); 

in

Foo foo = beanFactory.getBean(Foo.class); 

I vantaggi sono evidenti: la sicurezza di tipo, codice meno contorto, costanti meno inutili, ecc. In genere tali linee sono situate in contesti legacy statici dove tale cablaggio è l'unica opzione.

Questo andava tutto bene fino a quando un giorno gli utenti hanno cominciato a lamentarsi della lentezza che si è presentata dagli interni di Spring. Così ho sparato un profiler per trovare un hotspot in

org.springframework.beans.factory.support.AbstractBeanFactory::doGetBean(String, Class<T>, Object[], boolean)

che ha una chiamata costosa per

Class.isAssignableFrom(anotherClass).

mi hanno rapidamente creato una piccola performance test per scoprire la differenza di velocità tra il nome di stringa e di tipo lookup è una convulsa volte (sto usando StaticApplicationContext per questo test FAIW)!

Durante l'indagine, ho trovato SPR-6870 che ha un numero elevato di voti ma per qualche motivo non viene risolto. Questo mi ha portato a an attempt to solve this problem che migliora in modo significativo la situazione, ma è ancora più lenta ~ 25 volte rispetto alla ricerca di String! Si scopre che questo tentativo risolve solo metà del problema: memorizza nella cache il nome del bean per salvare su O (n) iterazione, ma deve comunque chiamare lo isAssignableFrom per convalidare il tipo.

Il problema descritto non è solo relativo al mio scenario ma è anche per i bean che utilizzano @Autowired e può essere sentito duro nei casi in cui i bean vengono creati all'interno di un ciclo.

Una delle soluzioni sarebbe quella di sovrascrivere uno dei metodi di bean factory e memorizzare i risultati del controllo is-this-bean-of-the-type dello stesso tipo, ma chiaramente questo dovrebbe essere fatto in primavera e non nel mio codice.

Qualcun altro soffre di un problema simile e ha trovato una soluzione?

+0

Quindi, si desidera eseguire la registrazione automatica per tipo, ma senza eseguire alcun tipo di controllo? – GreyBeardedGeek

+0

Voglio la seconda chiamata contro lo stesso tipo per evitare il costoso controllo dei tipi. O almeno voglio la possibilità di specificare se è abilitato o disabilitato. La creazione di oggetti è una cosa così basilare che piccole ottimizzazioni come questa possono fare una grande differenza. – mindas

risposta

2

La maggior parte delle app di Spring collegano le cose all'avvio, piuttosto che catturare i bean dal contesto in fase di runtime. Anche se non modifichi il contesto dell'applicazione durante la normale esecuzione della tua app, non dovresti mai recuperare un bean più di una volta.

Dato che, se i vostri utenti si lamentano della lentezza, sembra che il vostro vero problema siano troppe ricerche di bean; il tuo uso di mezzi più lenti per farlo è appena emerso il vero problema.

Vorrei provare a passare a Java Config (configurare le dipendenze in Java, supportato in Spring 3.0 credo) e configurare l'app per collegare tutti i bean all'avvio. Questo ha anche il vantaggio che la tua app non si avvierà se le dipendenze non possono essere soddisfatte.

+0

Penso che quello che volevi veramente dire è "il mio problema è che sto usando Spring per questo" :) Per quanto riguarda Java Config - sì, questa è un'opzione di escape, ma continuo a pensare che il problema originale dovrebbe essere affrontato come sembra incidono (a giudicare dal conteggio in eccesso) molti altri utenti di Spring. – mindas

+0

Non ho mai avuto questo problema con Spring e l'ho usato su progetti abbastanza grandi. Il tempo di avvio dell'app è stato piuttosto lento, ma una volta che le cose sono state cablate, ha funzionato bene. Generalmente, abbiamo creato automaticamente un nome, ma avevamo anche una configurazione XML. Non abbiamo mai chiamato direttamente getBean. – davetron5000

+0

"Grandi progetti" possono avere diversi scenari. La tua tesi che non hai mai avuto questo problema è discutibile. Inoltre, dubito del suggerimento che l'utilizzo di Java Config (invece di XML, ad esempio) possa essere di aiuto in qualsiasi modo: se viene utilizzato lo stesso tipo di BeanFactory, esso soffrirà dello stesso problema. È l'implementazione dell'istanziazione dei bean factory che è rotta e non l'assembly. – mindas

5

Questo problema è ora risolto in primavera con la risoluzione di SPR-6870. Vedi i commenti della risoluzione lì per i dettagli. La correzione è disponibile dalle versioni 3.2.0.RELEASE e 3.1.2.

+1

Utilizziamo la molla 3.2.1, ma la maggior parte del tempo trascorso dall'applicazione durante l'avvio si avvia automaticamente per tipo. Eventuali suggerimenti? –

Problemi correlati