java spring - @Resource vs @Autowired




constructor injection (10)

Como nota aquí: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext y SpringBeanAutowiringSupport.processInjectionBasedOnServletContext NO funciona con la anotación @Resource . Entonces, hay diferencia.

¿Qué anotación, @Resource ( jsr250 ) o @Autowired (específica de Spring) debo usar en DI?

He utilizado con éxito tanto en el pasado, @Resource(name="blah") como @Autowired @Qualifier("blah")

Mi instinto es seguir con la etiqueta @Resource ya que ha sido ratificada por las personas jsr.
¿Alguien tiene fuertes pensamientos sobre esto?


La principal diferencia es que @Autowired es una anotación de resorte. Mientras que @Resource está especificado por el JSR-250, como usted mismo señaló. Así que el último es parte de Java, mientras que el primero es específico de Spring.

Por lo tanto, tienes razón al sugerir que, en cierto sentido. Encontré que la gente usa @Autowired con @Qualifier porque es más poderoso. Pasar de un marco a otro se considera muy improbable, si no mito, especialmente en el caso de Spring.


Esto es lo que obtuve del Manual de referencia de Spring 3.0.x :

Propina

Si pretende expresar la inyección guiada por anotación por nombre, no utilice principalmente @Autowired, incluso si es técnicamente capaz de referirse a un nombre de bean a través de los valores de @Qualifier. En su lugar, use la anotación JSR-250 @Resource, que se define semánticamente para identificar un componente objetivo específico por su nombre único, con el tipo declarado que es irrelevante para el proceso de coincidencia.

Como consecuencia específica de esta diferencia semántica, los beans que se definen a sí mismos como una colección o tipo de mapa no se pueden inyectar a través de @Autowired, porque la coincidencia de tipos no se aplica adecuadamente a ellos. Utilice @Resource para dichos beans, refiriéndose a la colección específica o al bean de mapa por nombre único.

@Autowired se aplica a campos, constructores y métodos de argumentos múltiples, lo que permite reducir las anotaciones de calificador en el nivel de parámetro. Por el contrario, @Resource solo se admite para campos y métodos de establecimiento de propiedades de bean con un solo argumento. Como consecuencia, quédese con calificadores si su objetivo de inyección es un constructor o un método de argumentos múltiples.


En la primavera pre-3.0 no importa cuál.

En la primavera 3.0 hay soporte para la anotación estándar ( JSR-330 ) @javax.inject.Inject : utilícela, con una combinación de @Qualifier . Tenga en cuenta que Spring ahora también es compatible con la meta-anotación @javax.inject.Qualifier :

@Qualifier
@Retention(RUNTIME)
public @interface YourQualifier {}

Para que puedas tener

<bean class="com.pkg.SomeBean">
   <qualifier type="YourQualifier"/>
</bean>

o

@YourQualifier
@Component
public class SomeBean implements Foo { .. }

Y entonces:

@Inject @YourQualifier private Foo foo;

Esto hace un menor uso de los nombres de cadena, que pueden estar mal escritos y son más difíciles de mantener.

En cuanto a la pregunta original: ambos, sin especificar ningún atributo de la anotación, realizan la inyección por tipo. La diferencia es:

  • @Resource permite especificar un nombre del bean inyectado
  • @Autowired permite marcarlo como no obligatorio.

Tanto @Autowired (o @Inject ) como @Resource funcionan igualmente bien. Pero hay una diferencia conceptual o una diferencia en el significado

  • @Resource significa conseguirme un recurso conocido por nombre . El nombre se extrae del nombre del setter o campo anotado, o se toma del nombre-Parámetro.
  • @Inject o @Autowired intentan conectar un componente apropiado por tipo .

Entonces, básicamente estos son dos conceptos bastante distintos. Desafortunadamente, la implementación de @Resource de @Resource tiene un @Resource incorporado, que se activa cuando falla la resolución por nombre. En este caso, recurre a la resolución por tipo @Autowired -kind. Si bien este respaldo es conveniente, en mi humilde opinión causa mucha confusión, porque las personas no son conscientes de la diferencia conceptual y tienden a usar @Resource para el @Resource automático basado en tipos.


Ambos son igualmente buenos. La ventaja de usar Resource está en el futuro si desea otro marco de DI distinto al de Spring, los cambios en su código serán mucho más simples. El uso de Autowired su código está estrechamente acoplado con resortes DI.


Cuando analice críticamente a partir de las clases básicas de estas dos anotaciones, se dará cuenta de las siguientes diferencias.

@Autowired utiliza AutowiredAnnotationBeanPostProcessor para inyectar dependencias.
@Resource utiliza CommonAnnotationBeanPostProcessor para inyectar dependencias.

A pesar de que usan diferentes clases de post-procesadores, todos se comportan de manera casi idéntica. Las diferencias se encuentran críticamente en sus caminos de ejecución, que he resaltado a continuación.

@Autowired / @Inject

1.Matches por tipo
2.Restricts por Calificadores
3.Matches por nombre

@Resource

1.Matches por nombre
2.Matches por tipo
3. Restricciones por Calificadores (ignoradas si la coincidencia se encuentra por nombre)


Me gustaría enfatizar un comentario de Jules sobre esta respuesta a esta pregunta. El comentario trae un enlace útil: blogs.sourceallies.com/2011/08/… . Le animo a que lo lea por completo, sin embargo aquí hay un breve resumen de su utilidad:

¿Cómo las anotaciones seleccionan la implementación correcta?

@Autowired y @Inject

  1. Partidas por tipo
  2. Restricciones por Calificadores
  3. Partidas por nombre

@Resource

  1. Partidas por nombre
  2. Partidas por tipo
  3. Restricciones por calificadores (ignorado si la coincidencia se encuentra por nombre)

¿Qué anotaciones (o combinación de) debo usar para inyectar mis frijoles?

  1. Nombre explícitamente su componente [@Component ("beanName")]

  2. Use @Resource con el atributo de name [@Resource (name = "beanName")]

¿Por qué no debería usar @Qualifier ?

Evite @Qualifier anotaciones de @Qualifier menos que desee crear una lista de beans similares. Por ejemplo, es posible que desee marcar un conjunto de reglas con una anotación específica de @Qualifier . Este enfoque simplifica la inyección de un grupo de clases de reglas en una lista que puede usarse para procesar datos.

¿La inyección de frijol ralentiza mi programa?

Analice paquetes específicos para componentes [context:component-scan base-package="com.sourceallies.person"] . Si bien esto resultará en más configuraciones de component-scan , reduce la posibilidad de que agregue componentes innecesarios a su contexto Spring.

Referencia: blogs.sourceallies.com/2011/08/…


@Resource menudo es utilizado por objetos de alto nivel, definidos a través de JNDI. @Autowired o @Inject serán utilizados por beans más comunes.

Que yo sepa, no es una especificación, ni siquiera una convención. Es más la forma lógica en que el código estándar usará estas anotaciones.


Para robar, las perillas de las puertas responden pero hacen un cambio que de otra manera me volvería loco como un pirata:

int arraySize = yourArrayList.size();
for (int i = 0; i < arraySize; i ++) {
    // i is the index
    // yourArrayList.get(i) is the element
}

alternativamente

int currentPosition = 0;
for (myItemType myItem :myArrayList) {
    // do stuff

    currentPosition++;
}






java spring dependency-injection annotations autowired