@ Ressource vs @ Autowired

Quelle annotation, @ ressource (jsr250 ) ou @ Autowired (spécifique au printemps) dois-je utiliser dans DI?

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

Mon instinct est de rester avec la balise @Resource car elle a été ratifiée par le peuple jsr.
Quelqu'un a des pensées fortes à ce sujet?

299
demandé sur Mahozad 2010-11-04 05:50:58

11 réponses

Dans spring pre-3.0, peu importe lequel.

Dans spring 3.0, il existe un support pour l'annotation standard (JSR-330) @javax.inject.Inject - Utilisez-la, avec une combinaison de @Qualifier. Notez que spring prend désormais également en charge la méta-annotation @javax.inject.Qualifier:

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

, Donc vous pouvez 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 fait moins usage des noms de chaîne, qui peuvent être Mal orthographiés et sont plus difficiles à maintenir.


Quant à la question initiale: les deux, sans spécifier d'attributs de l'annotation, effectuent l'injection par type. La différence est:

  • @Resource vous permet de spécifier un nom du bean injecté
  • @Autowired vous permet de le marquer comme non obligatoire.
157
répondu Bozho 2012-09-01 09:45:57

Deux @Autowired (ou @Inject) et @Resource fonctionner tout aussi bien. Mais il existe une différence conceptuelle ou une différence dans le sens

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

Donc, fondamentalement, ce sont deux concepts distincts. Malheureusement, l' Spring-implémentation de @Resource a un repli intégré, qui entre en jeu lorsque la résolution par nom échoue. Dans ce cas, il revient à la résolution @Autowired-kind par type. Bien que ce repli soit pratique, à mon humble avis, il provoque beaucoup de confusion, car les gens ne sont pas conscients de la différence conceptuelle et ont tendance à utiliser @Resource pour l'autowiring basé sur le type.

406
répondu Ichthyo 2016-10-10 10:58:35

La différence principale est, @Autowired est une annotation de printemps. Alors que @Resource est spécifié par le JSR-250, comme vous l'avez souligné vous-même. Donc, ce dernier fait partie de Java alors que le premier est spécifique au printemps.

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

69
répondu Adeel Ansari 2010-11-04 03:39:51

Je voudrais souligner un commentaire à partir 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, Mais voici un bref résumé de son utilité:

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

@Autowired et @Inject

  1. correspond par Type
  2. limite par qualificatifs
  3. correspond par Nom

@Resource

  1. Correspond par Nom
  2. correspond par Type
  3. limite par qualificatifs (ignoré si la correspondance est trouvée par nom)

Quelles annotations (ou combinaison de) dois-je utiliser pour injecter mes haricots?

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

  2. Utiliser @Resource avec name attribut [@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 spécifiques @Qualifier annotation. Cette approche simplifie l'injection d'un groupe de classes de règles dans une liste qui peut être utilisée pour le traitement des données.

L'injection de haricots ralentit-elle mon programme?

Analyse des paquets spécifiques pour les composants [context:component-scan base-package="com.sourceallies.person"]. Bien que cela se traduise par plus de configurations component-scan, cela réduit les chances que vous ajoutiez composants inutiles à votre contexte Spring.


Référence: Printemps Injection avec @Resource, @Autocâblés et @Inject

52
répondu Stephan 2017-05-23 12:18:36

C'est ce que j'ai obtenu du Printemps 3.0.x Manuel de référence :-

Astuce

Si vous avez l'intention d'exprimer une injection basée sur des annotations par nom, faites pas principalement utiliser @Autowired, même si est techniquement capable de se référant à un nom de bean via les valeurs @ Qualifier. Au lieu de cela, utiliser le JSR-250 @Resource annotation, qui est définie sémantiquement pour identifier un composant cible spécifique par son nom unique, avec le le type déclaré n'étant pas pertinent pour processus de correspondance.

Comme conséquence spécifique de cette différence sémantique, les haricots qui sont eux mêmes définis comme un type de collection ou de carte ne peuvent pas être injectés via @Autowired, car la correspondance de type n'est pas correctement applicable pour eux. Utilisez @Resource pour ces haricots, en se référant au spécifique collection ou carte bean par nom unique.

@ Autowired s'applique aux champs, aux constructeurs et aux arguments multiples méthodes, permettant de rétrécir à travers les annotations de qualificatif à le paramètre niveau. En revanche, @Resource n'est pris en charge que pour les champs et bean property setter méthodes avec un seul argument. En tant que conséquence, respectez les qualificatifs si votre cible d'injection est un constructeur ou une méthode multi-arguments.

38
répondu Kartik 2014-10-17 10:38:32

@Autowired + @ Qualifier ne fonctionnera qu'avec spring DI, si vous voulez utiliser un autre DI à l'avenir @Resource est une bonne option.

Une autre différence que j'ai trouvée très significative est que @Qualifier ne supporte pas le câblage dynamique des beans, car @Qualifier ne supporte pas l'espace réservé, alors que @Resource le fait très bien.

Par exemple: si vous avez une interface avec plusieurs implémentations comme ceci

interface parent {

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

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

}

Avec @ Autowired & @ Qualifier, vous devez définir un enfant spécifique application comme

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

Qui ne fournit pas d'espace réservé alors qu'avec @Resource vous pouvez mettre 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 cela aide quelqu'un:)

18
répondu Ali 2015-03-26 04:08:42

Les deux sont également bons. L'avantage d'utiliser Resource est à l'avenir si vous voulez un autre framework DI autre que spring, vos changements de code seront beaucoup plus simples. En utilisant Autowired votre code est étroitement couplé avec springs DI.

17
répondu Teja Kantamneni 2010-11-04 02:59:27

Avec @Resource Vous pouvez faire l'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 choses transactionnelles ou liées à la sécurité.

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

3
répondu Bohdan Levchenko 2017-06-20 20:25:51

@Resource est souvent utilisé par des objets de haut niveau, définis via JNDI. @Autowired ou @Inject seront utilisés par des haricots plus 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
répondu Nicolas Zozol 2014-03-07 18:06:05

Comme une note ici: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext et SpringBeanAutowiringSupport.processInjectionBasedOnServletContext ne fonctionne pas avec l'annotation@Resource. Donc, il y a différence.

0
répondu msangel 2013-06-17 17:12:02

Lorsque vous analysez de manière critique à partir des classes de base de ces deux annotations.Vous réaliserez 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-processeur, ils se comportent tous de manière presque identique. Les différences résident de manière critique dans leurs chemins d'exécution, que j'ai mis en évidence ci-dessous.

@Autowired / @Inject

1.Correspond par Type
2.Restreint par qualificateurs
3.Matchs par Nom

@Resource

1.Correspond par nom
2.Correspond par Type
3.Restreint par des qualificatifs (ignoré si la correspondance est trouvée par son nom)

0
répondu Amos Kosgei 2018-10-05 11:23:37