Primavera @Utilizzo automatico


218

Quali sono i pro e i contro dell'utilizzo di @Autowired in una classe che verrà cablata da Spring?

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

Probabilmente non lo capisco, ma a me sembra quasi un anti-pattern: le tue classi iniziano a rendersi conto che sono legate a un framework DI, piuttosto che essere 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 della tua app MVC tramite annotazioni anziché XML sembra che porterebbe a molte ricerche su "quale classe è mappata su questo URL?" "chi gestisce questo?". Mi piace avere un'unica fonte di configurazione
matt b

6
il termine "@Autowiring" sembra essere fuorviante qui. Come è anche possibile eseguire l'autowiring con la configurazione XML, la domanda originale deve essere riformulata come "Pro e contro dell'uso delle annotazioni Spring". La risposta fornita si concentra maggiormente sugli aspetti dell'autowiring e meno sugli aspetti dell'utilizzo delle annotazioni.
Neeme Praks,

Risposte:


253

Per molto tempo ho creduto che ci fosse un valore nell'avere una "configurazione centralizzata, dichiarativa" come i file xml che tutti usavamo. Poi mi sono reso conto che la maggior parte delle cose nei file non erano di configurazione : non sono mai state modificate da nessuna parte dopo lo sviluppo. Poi ho capito che "centralizzato" ha valore solo in sistemi piuttosto piccoli - solo in sistemi piccoli sarai mai in grado di eseguire il grok di un file di configurazione nel suo insieme . 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 è ancora un po 'dichiarativo. Questi non cambiano mai in fase di esecuzione e non lo sono mai dati di "configurazione" che qualcuno cambierà al volo - quindi penso che tenerli nel codice sia bello.

Uso il cablaggio automatico completo il più possibile. Lo adoro. Non tornerò alla primavera vecchio stile se non minacciato di sparare. Le mie ragioni per preferire completamente @Autowiredsono cambiate nel tempo.

In questo momento penso che il motivo più importante per l'utilizzo dell'autowiring sia che nel tuo sistema c'è un'astrazione in meno di cui tenere traccia. Il "nome bean" è effettivamente sparito. Si scopre che il nome del bean esiste solo a causa di xml. Quindi un intero strato di riferimenti indiretti astratti (dove si collegherebbe il nome "foo" del bean in "barra" del bean) è sparito. Ora installo direttamente l'interfaccia "Foo" nel mio bean e l'implementazione viene scelta dal profilo di runtime. Questo mi consente 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 all'implementazione" nel mio IDE e compare l'elenco delle implementazioni conosciute. Nella maggior parte dei casi c'è solo un'implementazione e vado subito in classe. Può' quale implementazione viene utilizzata (sostengo che il contrario è più vicino alla verità con il cablaggio xml - divertente come cambia la tua prospettiva!)

Ora potresti dire che è solo un livello molto semplice, ma ogni livello di astrazione che aggiungiamo ai nostri sistemi aumenta la complessità. Non credo 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 configurazione dell'ambiente di runtime di produzione. Potrebbero esserci altre configurazioni per il test e così via.

Direi che il pieno autowiring è il rubino su rotaie della primavera: abbraccia l'idea che esiste un modello di utilizzo normale e comune che la maggior parte dei casi d'uso segue. Con la configurazione XML, si consente un utilizzo della configurazione coerente / incoerente che potrebbe / potrebbe non essere previsto. Ho visto così tanta configurazione xml esagerare con incoerenze: viene refactored insieme al codice? Non ho pensato. Quelle variazioni ci sono per una ragione? Di solito no.

Difficilmente usiamo qualificatori nella nostra configurazione 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 l'autowiring: un repository dei clienti non implementa più l' Repository<Customer>interfaccia generica ma creiamo un'interfaccia CustomerRepositoryche si estende Repository<Customer>. A volte c'è anche un trucco o due quando si tratta di sottoclasse. Ma di solito ci indica semplicemente la direzione di una digitazione più forte, che trovo quasi sempre una soluzione migliore.

Ma sì, stai legando a un particolare stile di DI che principalmente fa primavera. Non creiamo più setter pubblici per le dipendenze (quindi potresti obiettare che siamo +1 nel dipartimento di incapsulamento / occultamento delle informazioni) Abbiamo ancora alcuni xml nel nostro sistema, ma l'xml contiene sostanzialmente solo le anomalie. Il completo autowiring si integra perfettamente con XML.

L'unica cosa di cui abbiamo bisogno ora è che @Component, @Autowirede il resto sia incluso in una JSR (come JSR-250 ), quindi non dobbiamo legarci con la primavera. Questo è il modo in cui le cose sono java.util.concurrentsuccesse in passato (le cose mi vengono in mente), quindi non sarei completamente sorpreso se ciò accadesse di nuovo.


5
Javax.annotation / javax.inject è supportato da spring, quindi non devi avere la dipendenza del codice da Spring.
Michael Wiles,

26

Per me ecco quello che mi piace / non mi piace di Spring e del cablaggio automatico.

Professionisti:

  • Il cablaggio automatico elimina la cattiva configurazione XML.
  • Annotazioni molto più facili da usare che ti permettono di iniettare direttamente usando campi, metodi setter o costruttori. Inoltre, consente di annotare e "qualificare" i bean iniettati.

Contro:

  • L'uso del cablaggio automatico e delle annotazioni ti rende dipendente dalle librerie Spring dove, come con la configurazione XML, potresti scegliere di eseguire con o senza Spring. Come hai detto, ti leghi a un framework DI.
  • Allo stesso tempo mi piace essere in grado di "qualificare" i bean, per me questo rende il codice davvero disordinato. Se devi 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 il problema della dipendenza è controverso. Ho lavorato a un progetto Spring MVC che utilizzava ampiamente il cablaggio automatico ed era un po 'difficile avvolgere la testa.

Penso che l'auto-cablaggio sia un gusto acquisito, una volta che ti ci abitui ti rendi conto di quanto sia potente, facile e molto meno mal di testa rispetto alla configurazione XML.


3
la configurazione XML diventa molto meno sgradevole se si utilizza la suite gratuita di Springsource Tool, che include il completamento automatico, i grafici a bean, ecc.
Sean Patrick Floyd,

Sono totalmente d'accordo con te sul fatto che l'auto-cablaggio diventi disordinato e dipendente dalle librerie di primavera! Non ho mai usato la configurazione XML e sto pensando che dovrei forse seguire questa strada?
James111,

15

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


1
Ho scoperto che javaconfig potrebbe persino essere una soluzione migliore per iniziare contesti parziali, il che è una grande vittoria Ma puoi combinarli abbastanza facilmente usando @ Autowired / @ Inject su costruttori (in altre parole, passa all'iniezione di costruttori).
krosenvold,

6

Si è discusso molto poco sul cambio di ambiente. 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 è abbastanza semplice con Spring EL, e non sono a conoscenza di nessuna bella soluzione con le annotazioni. Ne ho appena scoperto uno:

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

Dovrebbe funzionare, ma non una buona soluzione.


Ho aperto un thread separato su questo, e c'è una soluzione con la primavera @Profilese @Configuration: blog.springsource.org/2011/02/14/... Vedi anche l'altro thread: stackoverflow.com/questions/13490393/...
BTakacs

4

Sono passato a @Autowire. Mantenere la configurazione XML su qualsiasi cosa diversa da un piccolo progetto è diventato un compito a sé stante e la comprensione si è rapidamente degradata.

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


3

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

Annotazioni come @Component peggiorano ulteriormente le cose. Guida gli sviluppatori a rendere gli oggetti mutabili, poiché le dipendenze non possono più essere rese definitive, dato che è necessario fornire costruttori predefiniti. Le dipendenze devono essere iniettate tramite il setter pubblico o non controllate tramite @Autowired. [l'iniezione di dipendenza ancora peggiore è compromessa con le classi che istanziano le loro dipendenze, lo vedo ancora nel codice appena scritto!]. Con incontrollato intendo, nei sistemi di grandi dimensioni, quando sono disponibili più implementazioni (o elementi secondari) del tipo, è molto più complicato comprendere quale delle implementazioni era @Autowired, una complessità che rende molto più difficile lo studio dei bug. Significa anche che, presumibilmente, hai un profilo per l'ambiente di test e un altro per la produzione,

Mi attengo alla via di mezzo dove dichiaro le mie classi di configurazione, (configurazione Spring basata su Java usando @Configuration)

Dichiaro esplicitamente tutti i miei bean nelle classi di configurazione. Uso solo @Autowired nelle classi di configurazione, lo scopo è limitare la dipendenza da Spring alle classi di configurazione

@Configuration risiede in un pacchetto specifico, è l'unico posto dove viene eseguita la scansione primaverile. (Ciò accelera notevolmente l'orario di inizio nei grandi progetti)

Mi sforzo di rendere immutabili tutte le mie classi, 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 cambiare gli oggetti dopo che sono stati creati, riduce sostanzialmente i bug nel sistema di grandi dimensioni e riduce il tempo necessario per trovare un bug quando ne esiste uno.

Sembra anche che costringa gli sviluppatori a progettare meglio l'interazione tra le diverse parti del sistema. Problemi e bug diventano sempre più errori di compilazione, che riduce il tempo perso e migliora la produttività.


1

Ecco alcuni dei professionisti con esperienza

  • Semplifica la configurazione perché possiamo semplicemente usare l'annotazione @Autowire
  • Non voglio usare i metodi setter, quindi la classe sarà più pulita

Contro

  • Abbina strettamente al file xml anche se stiamo usando DI
  • Implementazione difficile da trovare (ma se stai usando buoni ID come Intellij, puoi sbarazzartene)

A partire dalle mie esperienze personali non ho usato molto l'annotazione @AutoWire ma in casi di test.


1

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

Questa è la mia lista

Pro:

  • Rimuovi la linea inutile da xml
  • Semplifica il debug del codice: quando apri una classe, puoi leggere ciò che hai nella classe
  • Sviluppo più rapido, è leggibile un progetto con 400 o più righe di XML?

Contro:

  • Non è un'implementazione Java standard, ma è possibile passare a utilizzare @Inject, che è un'API Java standard, quindi il bean rimane un Pojo
  • Non puoi semplicemente usare ovunque, connessione db e così via, ma è solo un'opinione, preferisco avere un posto dove leggere tutta la configurazione.

0

Per la mia comprensione, @Autowired è il migliore da usare mentre fai riferimento al riferimento dell'interfaccia e usa le sue funzioni di override, ma trovo solo un problema con questo è che a volte viene assegnato a null in fase di esecuzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.