2009-03-11 10 views
200

Quali sono i pro e i contro dell'uso di @Autowired in una classe che verrà cablata entro la primavera?Spring @Uso utente utilizzato

Giusto per chiarire, sto parlando specificatamente dell'annotazione @Autowired, non del cablaggio automatico in XML.

Probabilmente non lo capisco, ma a me sembra quasi un anti-modello: le classi iniziano a rendersi conto di essere legate a un framework DI, anziché essere solo POJO. Forse sono un ghiottone per punizione, ma mi piace avere la configurazione XML esterna per i bean, e mi piace avere collegamenti espliciti, quindi so esattamente cosa è cablato dove.

+4

Sono interessato anche a questo argomento: la configurazione dell'app MVC tramite annotazioni anziché XML sembra che porterebbe a molte ricerche su "quale classe è mappata a questo URL?" "chi sta gestendo questo?". Mi piace avere una singola fonte di configurazione –

+5

il termine "@Autowiring" sembra essere fuorviante qui.Poiché puoi anche eseguire l'autowiring con la configurazione XML, la domanda originale dovrebbe essere riformulata come "Pro e contro dell'uso delle annotazioni Spring". La risposta fornita si concentra più sugli aspetti dell'autowiring e meno sugli aspetti dell'uso delle annotazioni. –

+0

Possibile duplicato di [Understanding Spring @Autowired usage] (https://stackoverflow.com/questions/19414734/understanding-spring-autowired-usage) – tkruse

risposta

244

Per molto tempo ho creduto che ci fosse un valore nell'avere una "configurazione centralizzata, dichiarativa" come i file xml che usavamo tutti. Poi ho capito che la maggior parte delle cose nei file non era la configurazione - non è mai stata modificata da nessuna parte dopo lo sviluppo, mai. Poi ho capito che "centralizzato" ha valore solo in sistemi abbastanza piccoli - solo nei sistemi di piccole dimensioni sarai mai in grado di utilizzare un file di configurazione nel suo complesso. E qual è davvero il valore della comprensione del cablaggio nel suo insieme, quando gli stessi "cablaggi" sono per lo più duplicati dalle dipendenze nel codice? Quindi l'unica cosa che ho tenuto sono i metadati (annotazioni), che sono ancora di tipo dichiarativo. Questi non cambiano mai in runtime e sono mai "configurazione" dati che qualcuno cambierà al volo - quindi penso che tenerlo nel codice sia bello.

Uso il più completo cablaggio automatico il più possibile. Lo adoro. Non tornerò alla primavera vecchio stile a meno che non sia minacciato di pistola. Le mie ragioni per preferire completamente @Autowired sono cambiate nel tempo.

In questo momento, penso che il motivo più importante per utilizzare l'autowiring sia la presenza di un'astrazione in meno nel sistema per tenere traccia di. Il "nome del bean" è effettivamente sparito. Risulta che il nome del bean esiste solo a causa di xml. Quindi un intero livello di riferimenti indiretti astratti (dove si dovrebbe collegare il nome del bean "foo" alla "barra" del bean) non esiste più. Ora collego direttamente l'interfaccia "Foo" al mio bean e l'implementazione viene scelta dal profilo run-time. Questo mi consente di di lavorare con il codice quando si tracciano dipendenze e implementazioni. Quando vedo una dipendenza autowired nel mio codice, posso semplicemente premere il tasto "vai alla fase di implementazione" nel mio IDE e su viene l'elenco delle implementazioni conosciute. Nella maggior parte dei casi c'è solo un'implementazione e io sono direttamente in classe. Non può essere molto più semplice di quello, e so sempre quale implementazione viene utilizzata (asserisco che il contrario è più vicino alla verità con il cablaggio xml - divertente come cambia la tua prospettiva!)

Ora potresti diciamo che è solo un livello molto semplice, ma ogni strato di astrazione che aggiungiamo ai nostri sistemi aumenta la complessità di. Non penso davvero che l'xml abbia mai aggiunto alcun valore reale a qualsiasi sistema con cui ho lavorato.

La maggior parte dei sistemi con cui ho mai lavorato ha una sola una configurazione dell'ambiente di runtime di produzione. Potrebbero esserci altre configurazioni per test e così via.

Direi che l'autowiring completo è il ruby-on-rails di primavera: abbraccia l'idea che esiste un modello di utilizzo normale e comune che la maggior parte dei casi di utilizzo segue. Con la configurazione XML, il numero di telefono consente a di utilizzare in modo coerente o incoerente la configurazione che può/non può essere intesa. Ho visto così tanta configurazione xml esagerare con le incoerenze - viene refactored insieme al codice? Non pensiero Quelle variazioni ci sono per un motivo? Di solito no.

Nella nostra configurazione utilizziamo solo qualificatori e abbiamo trovato altri modi per risolvere queste situazioni. Questo è un chiaro "svantaggio" che incontriamo: abbiamo leggermente modificato il modo in cui codifichiamo per renderlo più fluido con lo scambio automatico: un repository clienti non implementa più l'interfaccia generica Repository<Customer> ma facciamo un'interfaccia CustomerRepository che estende Repository<Customer>. A volte c'è anche un trucco o due quando si tratta di sottoclassi. Ma di solito ci punta solo verso una tipizzazione più forte, che trovo quasi sempre una soluzione migliore.

Ma sì, stai legando a uno stile particolare di DI che per lo più fa primavera. Non rendiamo ancora più dipendenti pubblici per le dipendenze (Quindi potresti dire che siamo +1 nel reparto di incapsulamento/occultamento delle informazioni) Abbiamo ancora qualche xml nel nostro sistema, ma l'xml in pratica solo contiene le anomalie . Completamente autowiring si integra bene con xml.

L'unica cosa di cui abbiamo bisogno ora è per la @Component, @Autowired e il resto per essere inclusi in una JSR (come JSR-250), in modo che non c'è bisogno di legare con la primavera. È così che sono andate le cose in passato (mi viene in mente la roba java.util.concurrent), quindi non sarei del tutto sorpreso se ciò accadesse di nuovo.

+4

javax.annotation/javax.inject è supportato da spring, quindi non è necessario avere la dipendenza dal codice su Spring. –

26

Per me ecco cosa mi piace/non mi piace di Spring e di auto-cablaggio.

Pro:

  • Auto-wiring si libera di configurazione XML brutto.
  • Annotazioni molto più facili da usare che consentono di iniettare direttamente utilizzando campi, metodi setter o costruttori. Consente inoltre di annotare e "qualificare" i fagioli iniettati.

Contro:

  • Utilizzando auto-cablaggio e annotazioni ti rende dipendente da librerie di primavera dove come con configurazione XML si poteva scegliere di correre con o senza molla. Come hai detto tu, sei legato a un framework DI.
  • Allo stesso tempo mi piace essere in grado di "qualificare" i fagioli, per me questo rende il codice davvero disordinato. Se è necessario iniettare lo stesso bean in più punti, ho visto lo stesso nome di stringa ripetuto dappertutto. Per me questo sembra avere il potenziale per errori.

Ho iniziato a utilizzare l'auto-cablaggio quasi esclusivamente al lavoro perché dipendiamo così tanto dall'integrazione di Spring che comunque il problema delle dipendenze è discutibile. Ho lavorato a un progetto MVC di Spring che utilizzava l'auto-cablaggio in modo estensivo ed era un po 'difficile da spiegare.

Penso che l'auto-cablaggio sia un gusto acquisito, una volta che ci si abitua ci si rende conto di quanto sia potente, facile e molto meno mal di testa con cui lavorare rispetto alla configurazione XML.

+3

la configurazione xml diventa molto meno sgradevole se si utilizza la Suite di Springource Tool gratuita, che funzionalità di autocompletamento, grafici dei bean ecc. –

+0

Sono totalmente d'accordo con te sul cablaggio automatico che diventa disordinato e dipende dalle librerie primaverili! Non ho mai usato la configurazione XML e sto pensando che forse dovrei seguire questa strada? – James111

4

Sono passato a @Autowire. Mantenere la configurazione XML su qualcosa di diverso da un piccolo progetto è diventato un compito a sé stante e la comprensione è rapidamente degradata.

IntelliJ fornisce un buon supporto (non perfetto) per le annotazioni Spring.

14

Stiamo passando da @Autowire alla configurazione XML nel nostro grande progetto.Il problema è una prestazione di bootstrap molto bassa. Lo scanner di Autowiring carica tutte le classi dal classpath di ricerca di autowiring, quindi molte classi vengono caricate con entusiasmo durante l'inizializzazione di Spring.

+1

Ho trovato che javaconfig potrebbe anche essere una soluzione migliore per l'avvio di contesti parziali, che è una grande vittoria Ma puoi combinarli abbastanza facilmente usando @ Autowired/@ Inject sui costruttori (in altre parole, passa all'iniezione del costruttore). – krosenvold

3

La mia opinione su questo argomento è che la configurazione xml riduce la chiarezza del codice, specialmente nei sistemi di grandi dimensioni.

Le annotazioni come @Component rendono le cose ancora peggiori. Permette agli sviluppatori di rendere gli oggetti mutabili, poiché le dipendenze non possono essere rese definitive più tardi, dato che devono essere forniti costruttori predefiniti. Le dipendenze devono essere o iniettate tramite server pubblico o incontrollate tramite @Autowired. [l'iniezione di dipendenza ancora peggiore è compromessa con le classi che istanziano le loro dipendenze, lo vedo ancora nel codice appena scritto!]. Intendo dire che, in sistemi di grandi dimensioni, quando sono disponibili più implementazioni (o figli) del tipo, diventa molto più complicato capire quale delle implementazioni è stata @Autowired, una complessità che rende molto più difficile l'investigazione dei bug. Significa anche che, presumibilmente hai un profilo per l'ambiente di test e un altro per la produzione, i bug di produzione si verificano solo quando fa più male - in produzione, piuttosto che essere in grado di individuare i bug nell'ambiente di test, o anche meglio, a compilare il tempo!

mi attengo alla terra di mezzo in cui dichiaro la mia classe di configurazione (es), (configurazione Spring sulla base Java utilizzando @Configuration)

Dichiaro tutti i miei fagioli esplicitamente nella classe di configurazione (es). Uso solo @Autowired nella classe di configurazione (es), lo scopo è limitare la dipendenza su Spring alle classi di configurazione

La configurazione @ risiede in un pacchetto specifico, che è l'unico posto in cui viene eseguita la scansione a molla . (Che accelera il tempo di inizio sostanzialmente in grandi progetti)

Mi sforzo di rendere tutte le mie classi immutabili, in particolare l'oggetto dati, JPA, Hibernate e Spring, così come molte librerie di serializzazione sembrano minare questo. Mi allontano da tutto ciò che mi costringe a fornire setter, o rimuovere la parola chiave finale dalla mia dichiarazione di proprietà.

Ridurre le possibilità di modifica degli oggetti dopo la loro creazione, riduce sostanzialmente i bug nel sistema di grandi dimensioni e riduce il tempo di trovare un bug quando ne esiste uno.

Sembra inoltre che costringa lo sviluppatore a progettare meglio l'interazione tra le diverse parti del sistema. I problemi e gli errori diventano sempre più errori di compilazione, che riducono lo spreco di tempo e migliorano la produttività.

1

Ecco alcune delle esperienze
Pro

  • Rende più facile da configurare perché possiamo semplicemente usare @Autowire annotazione
  • non si desidera utilizzare metodi setter, quindi classe sarà più pulite

Contro

  • Strettamente paio di file XML, anche se stiamo usando DI
  • Difficile trovare applicazione (Ma se la vostra utilizzando buone idi come IntelliJ sicuro che si può sbarazzarsi di questo)

Come dei miei dati personali esperienze che non ho usato l'annotazione @AutoWire molto ma nei casi di test.

6

C'è stata una discussione molto piccola sul passaggio da un ambiente all'altro. La maggior parte dei progetti su cui ho lavorato è stato un vero problema per iniettare dipendenze a seconda dell'ambiente su cui stiamo lavorando. Con xml config è piuttosto semplice con Spring EL, e non sono a conoscenza di alcuna soluzione con annotazioni. Ne ho appena trovato uno:

@Value("#{${env} == "production" ? realService : dummyService}") 
    private SomeService service; 

Dovrebbe funzionare, ma non una bella soluzione imho.

+0

Ho aperto un thread separato su questo, e c'è una soluzione con Spring '@ Profili 'e' @ Configurazione': http://blog.springsource.org/2011/02/14/spring-3-1-m1- introducing-profile/Vedi anche l'altro thread: http://stackoverflow.com/questions/13490393/annotation-driven-dependency-injection-which-handles-different-environments – BTakacs

1

Mi piace molto scrivere con annotazioni, anziché XML. Secondo il manuale Spring e le ultime versioni, XML e Annotation hanno ottenuto lo stesso risultato.

Questa è la mia lista

Pro:

  • Rimuovere linea inutile da XML
  • Semplificare il debug del codice: quando si apre una classe, si può leggere quello che hai nella classe
  • Più veloce sviluppo, un progetto con 400 o più linee di XML è leggibile?

Contro:

  • non è l'implementazione standard di Java, ma è possibile passare ad utilizzare @Inject, che è un Java Standard Api, quindi il fagiolo rimangono un POJO
  • Non si può semplicemente utilizzare ovunque , connessione db e così via, ma è solo un'opinione, preferisco avere un posto dove leggere tutte le configurazioni.
0

Per la mia comprensione, @Autowired è il migliore da usare mentre si fa riferimento al riferimento all'interfaccia e utilizza le sue funzioni di override, ma trovo che il problema è che a volte è stato assegnato a null in fase di esecuzione.

Problemi correlati