web-dev-qa-db-fra.com

@Resource vs @Autowired

Quelle annotation, @ Ressource ( jsr25 ) ou @ Autowired (spécifique au printemps) dois-je utiliser en DI?

J'ai utilisé avec succès les deux, @Resource(name="blah") et @Autowired @Qualifier("blah")

Mon instinct est de rester avec le tag @Resource car il a été ratifié par le peuple jsr.
Quelqu'un a-t-il des idées bien arrêtées?

339
mlo55

Au printemps pré-3.0, peu importe lequel.

Au printemps 3.0, il existe un support pour l'annotation _@javax.inject.Inject_ ( JSR-3 ) standard - avec une combinaison de _@Qualifier_. Notez que spring prend également en charge la méta-annotation _@javax.inject.Qualifier_:

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

Donc tu peux avoir

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

ou

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

Puis:

_@Inject @YourQualifier private Foo foo;
_

Cela utilise moins les noms de chaîne, qui peuvent être mal orthographiés et sont plus difficiles à gérer.


En ce qui concerne la question initiale: les deux, sans spécifier d'attribut de l'annotation, effectuent une injection par type. La différence est:

  • _@Resource_ vous permet de spécifier le nom du bean injecté
  • _@Autowired_ vous permet de le marquer comme non obligatoire.
176
Bozho

@Autowired (ou @Inject) et @Resource fonctionnent aussi bien. Mais il y a une différence conceptuelle ou une différence de sens

  • @Resource signifie me procurer un ressource connue par son nom. Le nom est extrait du nom du créateur ou du champ annoté, ou du nom-paramètre.
  • @Inject ou @Autowired essayez de câbler un autre composant approprié par type.

Donc, fondamentalement, ce sont deux concepts bien distincts. Malheureusement, l'implémentation printanière de @Resource a un repli intégré qui prend effet lorsque la résolution par nom échoue. Dans ce cas, il revient au type de résolution de type @Autowired-. Bien que cette solution de repli soit pratique, elle crée beaucoup de confusion à mon humble avis, car les gens ne sont pas conscients de la différence conceptuelle et ont tendance à utiliser @Resource pour l'auto-câblage basé sur un type.

474
Ichthyo

La principale différence est que @Autowired est une annotation à ressort. Alors que @Resource est spécifié par la JSR-250, comme vous l’avez indiqué vous-même. Donc, le dernier fait partie de Java alors que le premier est spécifique à Spring.

Par conséquent, vous avez raison de suggérer cela, dans un sens. J'ai trouvé des gens utilisent @Autowired avec @Qualifier parce que c'est plus puissant. Passer d'un cadre à un autre est considéré comme très improbable, si ce n'est un mythe, en particulier dans le cas du printemps.

72
Adeel Ansari

Je voudrais souligner un commentaire de @ Jules sur cette réponse à cette question. Le commentaire apporte un lien utile: Spring Injection avec @Resource, @Autowired et @Inject . Je vous encourage à le lire entièrement, cependant voici un résumé rapide de son utilité:

Comment les annotations sélectionnent-elles la bonne implémentation?

@Autowired et @Inject

  1. Matches par type
  2. Restrictions par qualificatifs
  3. Matchs par Nom

@Resource

  1. Matchs par Nom
  2. Matches par type
  3. Limite par qualificatifs (ignoré si une correspondance est trouvée par nom)

Quelles annotations (ou combinaisons de) dois-je utiliser pour l'injection de mes haricots?

  1. Nommez explicitement votre composant [@Component ("beanName")]

  2. Utilisez @Resource avec l'attribut name [@Resource (name = "beanName")]

Pourquoi ne devrais-je pas utiliser @Qualifier?

Évitez les annotations @Qualifier sauf si vous souhaitez créer une liste de beans similaires. Par exemple, vous pouvez marquer un ensemble de règles avec une annotation spécifique @Qualifier. Cette approche simplifie l’injection d’un groupe de classes de règles dans une liste utilisable pour le traitement des données.

L'injection de haricots ralentit-elle mon programme?

Analyser des packages spécifiques pour les composants [context:component-scan base-package="com.sourceallies.person"]. Bien que cela entraîne davantage de configurations component-scan, cela réduit les chances que vous ajoutiez des composants inutiles à votre contexte Spring.


Référence: Injection de ressort avec @Resource, @Autowired et @Inject

63
Stephan

C’est ce que j’ai reçu du Manuel de référence Spring 3.0.x : -

Pointe

Si vous avez l'intention d'exprimer le nom de l'injection pilotée par une annotation, n'utilisez pas principalement @Autowired, même si elle est techniquement capable de faire référence à un nom de bean via les valeurs @Qualifier. Utilisez plutôt l'annotation @Resource JSR-250, qui est définie de manière sémantique pour identifier un composant cible spécifique par son nom unique, le type déclaré n'étant pas pertinent pour le processus de correspondance.

Conséquence spécifique de cette différence sémantique, les beans qui sont eux-mêmes définis comme un type de collection ou de mappage ne peuvent pas être injectés via @Autowired, car la correspondance des types ne leur est pas applicable. Utilisez @Resource pour ces beans, en faisant référence à la collection spécifique ou au bean map par nom unique.

@Autowired s'applique aux champs, aux constructeurs et aux méthodes multi-arguments, ce qui permet de réduire les annotations de qualificatif au niveau du paramètre. En revanche, @Resource est uniquement pris en charge pour les méthodes de définition de propriétés de champs et de beans avec un seul argument. Par conséquent, utilisez des qualificatifs si votre cible d’injection est un constructeur ou une méthode multi-argument.

38
Kartik

@Autowired + @Qualifier fonctionnera uniquement avec le printemps DI, si vous souhaitez utiliser un autre DI par la suite, @Resource est une bonne option.

une autre différence que j’ai trouvée très importante est que @Qualifier ne prend pas en charge le câblage de bean dynamique, car @Qualifier ne prend pas en charge l’espace réservé, alors que @Resource le fait très bien.

Par exemple: si vous avez une interface avec plusieurs implémentations comme celle-ci

interface parent {

}
@Service("actualService")
class ActualService implements parent{

}
@Service("stubbedService")
class SubbedService implements parent{

}

avec @Autowired & @Qualifier, vous devez définir une implémentation enfant spécifique telle que

@Autowired
@Qualifier("actualService") or 
@Qualifier("stubbedService") 
Parent object;

qui ne fournit pas d'espace réservé alors qu'avec @Resource, vous pouvez placer un espace réservé et utiliser un fichier de propriétés pour injecter une implémentation enfant spécifique, comme

@Resource(name="${service.name}")
Parent object;  

où service.name est défini dans le fichier de propriétés comme

#service.name=actualService
 service.name=stubbedService

J'espère que ça aide quelqu'un :)

20
Ali

Les deux sont également bons. L’avantage d’utiliser Resource est qu’à l’avenir, si vous souhaitez utiliser un autre framework d’ID que le printemps, les modifications de votre code seront beaucoup plus simples. En utilisant Autowired, votre code est étroitement associé aux ressorts DI.

16
Teja Kantamneni

Lorsque vous analysez de manière critique à partir des classes de base de ces deux annotations, vous constaterez les différences suivantes.

@Autowired utilise AutowiredAnnotationBeanPostProcessor pour injecter des dépendances.
@Resource utilise CommonAnnotationBeanPostProcessor pour injecter des dépendances.

Même s'ils utilisent différentes classes de post-processeurs, ils se comportent tous de manière presque identique. Les différences portent essentiellement sur leurs chemins d'exécution, que j'ai soulignés ci-dessous.

@Autowired / @Inject

1. Correspondances par type
2.Règles par qualificatifs
3. Correspondances par nom

@Resource

1. Correspondances par nom
2. Correspondances par type
3.Restricts by Qualifiers (ignoré si une correspondance est trouvée par nom)

10
Amos Kosgei

Avec @Resource, vous pouvez effectuer une auto-injection de bean. Cela peut être nécessaire pour exécuter toute la logique supplémentaire ajoutée par les post-processeurs de bean, comme les éléments transactionnels ou liés à la sécurité.

Avec Spring 4.3+, @Autowired est également capable de le faire.

4
Bohdan Levchenko

@Resource est souvent utilisé par des objets de haut niveau, définis via JNDI. @Autowired ou @Inject sera utilisé par plus de haricots communs.

Pour autant que je sache, ce n'est pas une spécification, ni même une convention. C'est plus la manière logique que le code standard utilisera ces annotations.

2
Nicolas Zozol

Comme note ici: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext et SpringBeanAutowiringSupport.processInjectionBasedOnServletContextNE PAS travailler avec @Resource annotation. Donc, il y a une différence.

0
msangel