Dal momento che tutti i developer java sono ormai orientati (o si stanno orientando) verso l’utilizzo delle annotazioni, la differenza tra le annotazioni @Autowired e @Inject è una delle domande più frequenti quando si parla del framework Spring. L’Autowiring è il processo per mezzo del quale Spring definisce le dipendenze tra bean, sollevando lo sviluppatore da doverle definire esplicitamente. L’annotazione @Autowired è utilizzata allo scopo, definendo i punti di iniezione. È possibile utilizzarla infatti annotando campi e costruttori o metodi per indicare il framework le dipendenze del bean.
L’ annotazione @Inject ha la stessa funzione, ma la differenza principale tra essi è che @Inject è un’annotazione standard per l’iniezione di dipendenza mentre @Autowired è una specifica di Spring. Poiché Spring non è l’unico framework che prevede la dependency injection (DI), se si modifica il container e si utilizza un altro framework di DI (es. Google Guice), è necessario riconfigurare l’applicazione daccapo.
Potenzialmente è possibile evitare questo sforzo di sviluppo utilizzando annotazioni standard, come quelle definite nella specifica JSR-330 ad esempio @Inject, @Named, @Qualifier, @Scope e @Singleton. Un bean dichiarato auto-wired utilizzando @Inject funzionerà se si utilizza il framework Guice che Spring, e potenzialmente con qualsiasi altro contenitore DI che supporta le annotazioni JSR-330.
@Autowired vs @Inject
Se si conosce Hibernate e JPA si può vedere lo standard JSR-330 come una estensione delle annotazioni JPA che standardizzano il mapping Object Relational in tutto il framework. Quando si utilizzano annotazioni come @Entity, il codice non funzionerà solamente con Hibernate ma anche con altri strumenti e framework ORM, come ad esempio TopLink.
Sebbene simili, in quanto @Autowired e @Inject fondamentalmente servono allo stesso scopo, ci sono diverse differenze tra di loro, che vogliamo riepilogare brevemente:
- La prima e più importante differenza tra l’ annotazione
@Autowirede@Injectè che l’annotazione @Inject è disponibile solo dalla versione 3.0 di Spring in poi. Quindi se si desidera utilizzare l’iniezione attraverso annotazioni nella versione 2.5 del framework, allora deve essere obbligatoriamente utilizzata l’annotazione@Autowired. - La seconda differenza tra queste due annotazioni è che, diversamente da
@Autowired, l’annotazione@Injectrichiede l’attributo booleano required. Questo indica al framework se sollevare o meno una eccezione nel caso in cui la dipendenza non può essere risolta, rendendo di fatto la dipendenza opzionale. - La terza e più importante differenza tra le due annotazioni è che
@Autowiredè specifica di Spring mentre@Injectè lo standard per l’iniezione di dipendenza definita in JSR-330. In generale, è quindi raccomandabile utilizzare l’annotazione standard per la DI, a maggior ragione se si pensa che è supportata da Spring e che può essere utilizzata in combinazione con altre annotazioni di del framework come@Valuee@Lazy. - L’annotazione
@Autowiredè stata aggiunta nella versione 2.5 di Spring al fine di guidare l’iniezione delle dipendenze per mezzo di annotazioni. Lavora in combinazione con l’annotazione@Componente la direttiva<context: component-scan/>. Dalla versione 3.0, Spring supporta la specifica JSR-330 e quindi le relative annotazioni, quali@Inject,@Namede@Singleton. Sono inoltre state aggiunte ulteriori annotazioni, quali@Primary,@Lazye@DependsOn (riferirsi al libro Spring in Action 4th Edition per saperne di più sulle annotazioni specifiche di Spring). - L’ annotazione
@Injectportabile. Poiché@Autowiredè specifico per il framework Spring, nel momento in cui si decide di utilizzare un framework alternativo per la DI (es. Guice) sarà necessario re-implementare tutta la logica di iniezione delle dipendenza, anche se l’applicazione rimane invariata.
Conclusioni
In conclusione poiché il framework Spring è il più popolare container per DI e IOC per le applicazione Java, l’annotazione @Autowired è più comune di @Inject che è meno conosciuta. Ma dal punto di vista della portabilità, è meglio utilizzare @Inject, soprattutto se si utilizza la versione Spring dalla 3.0 in poi.
Riepiloghiamo quanto detto con la seguente tabella.
