Sviluppo in Spring Boot da poco più di un anno, ma devo ancora comprendere i vantaggi dellutilizzo di un costruttore Autowired e mi chiedevo se qualcuno potesse spiegami questo e quale sarebbe considerata la migliore pratica.
Supponiamo che io abbia un bean come segue
@Component public class MyBean { void doSomeStuff() { } }
E ho un servizio che ha una dipendenza da quel bean
@Service public class MyServiceImpl implements MyService { private MyBean myBean; }
Per me, il modo più semplice per iniettare la dipendenza in questa classe sarebbe semplicemente annotare la variabile con @Autowired
@Service public class MyServiceImpl implements MyService { @Autowired private MyBean myBean; }
Ma ci sono altri posti online (e anche altri sviluppatori nel mio team) che preferiscono qualcosa di simile a questo approccio:
@Service public class MyServiceImpl implements MyService { private MyBean myBean; @Autowired public MyServiceImpl(MyBean myBean) { this.myBean = myBean; } }
Per me, usare un costruttore del genere è semplicemente codice ridondante. Il cablaggio automatico del bean è molto più semplice e diretto di quello che mi sembra essere un codice boilerplate.
Commenti
Risposta
Utilizzi un vero costruttore per gli stessi motivi per cui usi getter e setter pubblici invece di rendere pubbliche variabili private.
Alcuni esempi di vita reale: i telefoni cellulari non sono ammessi in luoghi fisici sicuri e sensibili alle informazioni. Qualsiasi comunicazione con quella posizione sicura deve avvenire attraverso un protocollo di comunicazione stabilito in modo sicuro, controllato e crittografato, non di nascosto da un canale di comunicazione canaglia non monitorato e incontrollato.
Durante un concerto, non permetti alle persone di getta le cose oltre la recinzione a qualcuno che è già allo stadio. Qualunque cosa in entrata o in uscita deve passare attraverso un cancello.
Se questo è tutto ciò che cè nel tuo esempio di codice, allora appare come boilerplate inutilmente prolisso. Ma spesso facciamo altre cose nel costruttore oltre allimpostazione variabili private, come la convalida. In molti linguaggi di programmazione, la modifica del modo in cui esegui questa operazione dopo il fatto è una modifica del binario, quindi fornire il costruttore in anticipo può essere un passaggio sensato.
Infine, la classe dovrebbe essere in grado di funzionare indipendentemente dallinserimento di dipendenze. Se si inserisce unannotazione su un membro privato, ma non si include un costruttore , hai essenzialmente legato strettamente quella classe al contenitore DI e la classe non funzionerà senza di essa.
Commenti
- " A un concerto, non ' permetti alle persone di gettare oggetti oltre il recinto a qualcuno che ' s già nello stadiu m. Qualsiasi cosa in entrata o in uscita deve passare attraverso un cancello. " Ma non ' non vedo come lutilizzo di un costruttore renda il cablaggio automatico più sicuro? Se non ci fossero requisiti del costruttore (come la convalida), sarebbe di qualche vantaggio utilizzare un costruttore?
- Rendi possibile aggiungere la convalida in un secondo momento senza interrompere la compatibilità binaria.
- Inoltre , tieni presente che i membri privati dovrebbero restare privati. Questo ' è un po il punto centrale dellavere membri privati.
- Il punto centrale è consentire buone pratiche di progettazione compatibili con @Autowire. Avere costruttori è la cosa PIÙ naturale in OOP. Il contrario, (ciò che chiami diretto e più semplice) è piuttosto spaventoso. Non ci sono vantaggi reali nella rimozione dei costruttori, ' non è affatto semplice. I costruttori sono tra i metodi più semplici in OOP.Di per sé, di solito hanno una complessità minima che vale la pena implementare la magia di Spring IoC
- Per quello che vale ', Java tende ad essere un linguaggio molto verboso comunque. Se ' stai cercando di domare un po di quella verbosità, è probabile che leliminazione dei costruttori non faccia molto male.
To me, using a constructor like that is simply redundant code. Autowiring the bean is much simpler and straightforward than what appears to me to be boilerplate code.
e non sei preoccupato per la magia di iniettare un bean in una variabile instace che è privata e non ha setter? Non siete preoccupati per lenorme debito tecnico che questo sta generando su di voi, i vostri colleghi? Non sei preoccupato di trasmettere troppo il paradigma magico di Spring ' invece delle buone pratiche di progettazione?