¿Cuál es la diferencia entre @Inject y @Autowired en Spring Framework? ¿Cuál usar bajo qué condición?

695

Estoy revisando algunos blogs en SpringSource y en uno de los blogs, el autor está usando @Injecty supongo que él también puede usar @Autowired.

Aquí está el fragmento de código:

@Inject private CustomerOrderService customerOrderService;

No estoy seguro de la diferencia entre @Injecty @Autowiredagradecería si alguien explicara su diferencia y cuál usar en qué situación.

Rachel
fuente
3
No tengo una respuesta, ya que también soy nuevo en esto, pero esto podría ayudar a sakaenakajima.wordpress.com/2010/08/10/…
Sagar V
2
La diferencia entre '@Inject' y '@Autowired' se explica bien en este artículo alextheedom.wordpress.com/2016/02/13/…
Alex Theedom

Respuestas:

720

Suponiendo que aquí te refieres a las javax.inject.Injectanotaciones. @Injectforma parte del estándar Java CDI ( Contexts and Dependency Injection ) introducido en Java EE 6 (JSR-299), lea más . Spring ha optado por apoyar el uso como @Injectsinónimo de su propia @Autowiredanotación.

Entonces, para responder a su pregunta, @Autowiredes la propia anotación de Spring. @Injectes parte de una nueva tecnología Java llamada CDI que define un estándar para la inyección de dependencia similar a Spring. En una aplicación Spring, las dos anotaciones funcionan de la misma manera que Spring ha decidido admitir algunas anotaciones JSR-299 además de las suyas.

papilla
fuente
115
Entonces, en teoría, si usó @Inject, podría reemplazar spring con otro marco DI, por ejemplo, Guice, e inyectar sus dependencias de la misma manera.
Alex Barnes
71
A riesgo de ser pedante: @Injectes un JSR (JSR-330) separado del CDI (JSR-299).
Brad Cupit
36
Si confía solo en las anotaciones JSR- *, seguro, puede reemplazar su marco DI. ¿Pero lo harás? Una vez que haya comenzado a usar Spring, es probable que haya usado mucho más que solo DI. No solo harás un cambio; e incluso si lo hace, no son solo algunas búsquedas y reemplazos lo que hará o romperá el movimiento. Por otro lado, las propias anotaciones de Spring le ofrecen mucha más funcionalidad. Dominar un buen marco te dará más que apenas usar muchos.
Agoston Horvath
18
Estoy de acuerdo con usted en que no cambiamos los marcos de DI a menudo. Sin embargo, si nuestro código fuente tiene múltiples paquetes y si desea construir un paquete común que desea compartir en múltiples proyectos y luego ir con la @Injectanotación JSR, es mejor que usar lo @Autowiredque bloquea su base de código con Spring DI.
Aditya
3
Usar @Injectsolo no garantizará la independencia del marco. También necesitaría declarar frijoles inyectables sin mecanismos dependientes del marco como Spring's @Componento application.xml, pero usar @Namedy @Singletona nivel de clase. No tengo idea si algún proyecto de Spring realmente declara frijoles así hoy, incluso nunca escuché de ningún proyecto que migró de Spring a JEE ...
Marcus K.
162

Aquí está una entrada de blog que compara @Resource, @Injecty @Autowired, y parece hacer un trabajo bastante completa.

Desde el enlace:

Con la excepción de las pruebas 2 y 7, la configuración y los resultados fueron idénticos. Cuando miré debajo del capó, determiné que la anotación '@Autowired' y '@Inject' se comportan de manera idéntica. Ambas anotaciones usan el 'AutowiredAnnotationBeanPostProcessor' para inyectar dependencias. '@Autowired' y '@Inject' se pueden usar intercambiables para inyectar Spring beans. Sin embargo, la anotación '@Resource' usa 'CommonAnnotationBeanPostProcessor' para inyectar dependencias. Aunque usan diferentes clases de postprocesador, todos se comportan de manera casi idéntica. A continuación se muestra un resumen de sus rutas de ejecución.

Las pruebas 2 y 7 indican que las referencias del autor son 'inyección por nombre de campo' y 'un intento de resolver un bean utilizando un calificador incorrecto', respectivamente.

La conclusión debería darle toda la información que necesita.

nicholas.hauschild
fuente
44
Ese artículo es una gran explicación de las tres anotaciones. Tuve que volver a leerlo después del primer golpe; Pero, un excelente artículo.
Thomas
1
¡Muchas gracias! El artículo respondió a varias de mis respuestas en mi búsqueda de encontrar las diferencias y similitudes entre Spring y JavaEE, así como algunas otras preguntas que tenía.
Kevin Cruijssen
36

Para manejar la situación en la que no hay cableado, los beans están disponibles con el @Autowired requiredatributo establecido en false.

Pero cuando se usa @Inject, la interfaz del proveedor funciona con el bean, lo que significa que el bean no se inyecta directamente sino con el proveedor.

Amits
fuente
8
Esto es muy importante y se ha pasado por alto en las respuestas más votadas.
Igor Donin
Por defecto, el parámetro requerido se establece en verdadero para Autowired. Ref: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
tranquilo
25

A partir de la primavera 3.0, Spring ofrece soporte para JSR-330 anotaciones de inyección de dependencia ( @Inject, @Named, @Singleton).

Hay una sección separada en la documentación de Spring sobre ellos, que incluye comparaciones con sus equivalentes de Spring.

Andre Steingress
fuente
Pregunta aquí, ¿qué quieres decir cuando dices que Spring admite JSR? ¿El contenedor no admite JSR independientemente de Spring, y un requisito para que el contenedor sea compatible con J2EE? ¿Quieres decir que envuelve la funcionalidad? Si Spring no lo "admitió", ¿la anotación de Java todavía no funcionaría de manera predeterminada?
Dan Chase
No es imprescindible ejecutar Spring en un contenedor JEE, también puede usarlo en un contenedor de servlet / JSP como Tomcat y aún tener el soporte JSR-330. Spring es un contenedor DI separado, no "intercambia" beans CDI con el servidor JEE host si eso es lo que quiere decir. Puede usar CDI en un contenedor JEE o Spring beans, pero no puede usar ambos (listos para usar).
Andre Steingress
22

La diferencia clave (notada al leer Spring Docs ) entre @Autowiredy @Injectes que @Autowiredtiene el atributo 'requerido' mientras que @Inject no tiene el atributo 'requerido'.

Suerte
fuente
¿Qué quieres decir con requerido?
mattyman
2
@mattymanme De los documentos, "De forma predeterminada, el cableado automático falla siempre que haya cero beans candidatos disponibles; el comportamiento predeterminado es tratar los métodos, constructores y campos anotados como indicativos de dependencias requeridas. Este comportamiento se puede cambiar configurando el atributo requerido como falso ". Por ejemplo: en @Autowired(required=false)términos simples, "el requiredatributo indica que la propiedad no es necesaria para fines de cableado automático, la propiedad se ignora si no se puede cablear automáticamente".
Lucky
buscar en el código fuente interfaz pública Autowired {/ ** * Declara si se requiere la dependencia anotada. * / boolean required () default true; } public interface Inject {}
tarn
15

Mejor use @Inject todo el tiempo. Debido a que es el enfoque de configuración de Java (proporcionado por Sun) lo que hace que nuestra aplicación sea independiente del marco. Así que si saltas también tus clases funcionarán.

Si usa @Autowired, solo funcionará con spring porque @Autowired es una anotación proporcionada por spring.

tech.yenduri
fuente
13
El sol esta muerto. Larga vida al sol.
Amrinder Arora
66
¿Con qué frecuencia vas a cambiar el marco? Sólo curioso
Kay
En la mayoría de los proyectos, vi Autowired en lugar de Inject. Entiendo la lógica de la respuesta, pero no puedo votar.
Witold Kaczurba
13

@Autowired La anotación se define en el marco de Spring.

@InjectLa anotación es una anotación estándar, que se define en la "Inyección de dependencia para Java" estándar (JSR-330) . Spring (desde la versión 3.0) admite el modelo generalizado de inyección de dependencia que se define en el estándar JSR-330. (Los marcos de Google Guice y el marco de Picocontainer también admiten este modelo).

Con @Injectse puede inyectar la referencia a la implementación de la Providerinterfaz, lo que permite inyectar las referencias diferidas.

Anotaciones @Injecty @Autowired- es analogías casi completas. Además de la @Autowiredanotación, la @Injectanotación se puede usar para propiedades de enlace automático, métodos y constructores.

A diferencia de la @Autowiredanotación, la @Injectanotación no tiene requiredatributo. Por lo tanto, si no se encuentran las dependencias, se generará una excepción.

También hay diferencias en las aclaraciones de las propiedades de unión. Si hay ambigüedad en la elección de los componentes para la inyección, @Namedse debe agregar el calificador. En una situación similar para la @Autowiredanotación se agregará el @Qualifiercalificador (JSR-330 define su propia @Qualifieranotación y, a través de este calificador, @Namedse define la anotación ).

Arash
fuente
Aunque el '@Inject' no tiene un atributo requerido, el estado de Java Docs: Se requiere la inyección de miembros anotados con '@Inject'. Lo que parece implicar que si no se encuentra un miembro, su inyección fallará. Ver documentos de Java: docs.oracle.com/javaee/7/api/javax/inject/Inject.html
Alex Theedom
12

@Inject no tiene atributo 'requerido'

Mykhaylo Adamovych
fuente
12

Además de lo anterior:

  1. El alcance predeterminado para @Autowiredbeans es Singleton, mientras que el uso de la @Injectanotación JSR 330 es como el prototipo de Spring .
  2. No hay equivalente de @Lazy en JSR 330 usando @Inject.
  3. No hay equivalente de @Value en JSR 330 usando @Inject.
Keyur Vyas
fuente
0

La @Injectanotación es una de la colección de anotaciones JSR-330. Esto tiene rutas de ejecución Match by Type, Match by Qualifier, Match by Name. Estas rutas de ejecución son válidas tanto para el setter como para la inyección de campo. El comportamiento de la @Autowiredanotación es el mismo que la @Injectanotación. La única diferencia es que la @Autowiredanotación es parte del marco Spring. @AutowiredLa anotación también tiene las rutas de ejecución anteriores. Así que recomiendo el @Autowiredpara su respuesta.

Kushani5j
fuente