java - ejemplo - spring constructor injection annotation
@Resource vs @Autowired (11)
@Autowired + @Qualifier funcionará solo con Spring DI, si desea usar otra DI en el futuro, @Resource es una buena opción.
Otra diferencia que encontré muy significativa es que @Qualifier no admite el cableado dinámico de beans, ya que @Qualifier no admite marcadores de posición, mientras que @Resource lo hace muy bien.
Por ejemplo: si tiene una interfaz con múltiples implementaciones como esta
interface parent {
}
@Service("actualService")
class ActualService implements parent{
}
@Service("stubbedService")
class SubbedService implements parent{
}
con @Autowired y @Qualifier necesita establecer una implementación secundaria específica como
@Autowired
@Qualifier("actualService") or
@Qualifier("stubbedService")
Parent object;
que no proporciona marcador de posición mientras que con @Resource puede colocar marcador de posición y usar el archivo de propiedades para inyectar una implementación secundaria específica, como
@Resource(name="${service.name}")
Parent object;
donde service.name se establece en el archivo de propiedades como
#service.name=actualService
service.name=stubbedService
Espero que ayude a alguien :)
¿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?
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.
Como nota aquí: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext
y SpringBeanAutowiringSupport.processInjectionBasedOnServletContext
NO funciona con la anotación @Resource
. Entonces, hay diferencia.
Con @Resource
puede realizar la autoinyección de frijoles, podría ser necesario para ejecutar toda la lógica adicional agregada por los postprocesadores de frijoles, como cosas transaccionales o relacionadas con la seguridad.
Con Spring 4.3+ @Autowired
también es capaz de hacer esto.
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)
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.
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.
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.
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
- Partidas por tipo
- Restricciones por Calificadores
- Partidas por nombre
@Resource
- Partidas por nombre
- Partidas por tipo
- Restricciones por calificadores (ignorado si la coincidencia se encuentra por nombre)
¿Qué anotaciones (o combinación de) debo usar para inyectar mis frijoles?
Nombre explícitamente su componente [@Component ("beanName")]
Use
@Resource
con el atributo dename
[@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/…
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.
@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.