Domanda

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 per 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.

È stato utile?

Soluzione

Per molto tempo ho creduto che ci fosse un valore nell'avere un " centralizzato, dichiarativo, configurazione " come i file xml che usavamo tutti. Poi ho capito che la maggior parte delle cose nei file non era configurazione - non è mai stata cambiata da nessuna parte dopo lo sviluppo, mai. Poi ho capito che & Quot; & Centralizzato; ha valore solo in sistemi abbastanza 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 lo stesso & Quot; cablaggi & Quot; 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 mai cambiano in fase di esecuzione e sono mai & Quot; configurazione & Quot; dati 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 @Autowired sono 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. & Quot; nome bean & Quot; è effettivamente andato. 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 bean-name & Quot; foo & Quot; nel bean & Quot; bar & Quot;) è sparito. Ora collego il & Quot; Foo & Quot; interfaccia direttamente con il mio bean e l'implementazione è scelta dal profilo di runtime. Questo mi permette di lavorare con il codice quando tracciamo dipendenze e implementazioni. Quando vedo una dipendenza autowired nel mio codice, posso semplicemente premere & Quot; andare all'implementazione & Quot; digitare il mio IDE e in alto arriva l'elenco delle implementazioni conosciute. Nella maggior parte dei casi c'è solo un'implementazione e vado subito in classe. Non può essere molto più semplice di così, e so sempre esattamente quale implementazione viene utilizzata (sostengo che il contrario è più vicino alla verità con il cablaggio xml - divertente come cambia la tua prospettiva!)

Ora puoi dire che è solo un livello molto semplice, ma ogni livello di astrazione che aggiungiamo ai nostri sistemi aumenta 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 hanno solo una una 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, permetti un uso 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.

Nella nostra configurazione difficilmente utilizziamo i qualificatori e abbiamo trovato altri modi per risolvere queste situazioni. Questo è un chiaro & Quot; svantaggio & Quot; incontriamo: abbiamo leggermente modificato il modo in cui codifichiamo per renderlo più fluido con l'autowiring: un repository dei clienti non implementa più l'interfaccia generica Repository<Customer> ma creiamo un'interfaccia CustomerRepository che si estende @Component. 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 sia quasi sempre una soluzione migliore.

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

L'unica cosa di cui abbiamo bisogno ora è che java.util.concurrent, <=> e il resto siano inclusi in una JSR (come JSR-250 ), quindi non dobbiamo collegarci con la primavera. Questo è il modo in cui le cose sono accadute in passato (le cose <=> mi vengono in mente), quindi non sarei del tutto sorpreso se ciò accadesse di nuovo.

Altri suggerimenti

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

Pro:

  • 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 avvolgermi 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.

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 percorso di classe di ricerca di autowiring, quindi molte classi vengono caricate con impazienza durante l'inizializzazione di Spring.

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 buona soluzione con le annotazioni. Ne ho appena scoperto uno:

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

Dovrebbe funzionare, ma non una buona soluzione imho.

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.

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 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, diventa 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, i tuoi 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 tempo di compilazione!

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à.

Riducendo le possibilità di cambiare gli oggetti dopo la loro creazione, si riducono sostanzialmente i bug nel sistema di grandi dimensioni e si riduce il tempo 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à.

Ecco alcune esperienze
Pro

  • 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 così tanto l'annotazione @AutoWire ma nei casi di test.

Adoro davvero 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, un progetto con 400 o più righe di XML è leggibile?

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.

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 a volte che è assegnato a null in fase di esecuzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top