Quelle est la différence entre @Inject et @Autowired dans Spring Framework? Lequel utiliser dans quelle condition?

695

Je passe par quelques blogs sur SpringSource et dans l'un des blogs, l'auteur utilise @Injectet je suppose qu'il peut également utiliser @Autowired.

Voici le morceau de code:

@Inject private CustomerOrderService customerOrderService;

Je ne suis pas sûr de la différence entre @Injectet @Autowiredj'apprécierais que quelqu'un explique sa différence et laquelle utiliser dans quelle situation?

Rachel
la source
3
Je n'ai pas de réponse, car je suis nouveau à cela aussi, mais cela pourrait aider sakaenakajima.wordpress.com/2010/08/10/…
Sagar V
2
La différence entre '@Inject' et '@Autowired' est bien expliquée dans cet article alextheedom.wordpress.com/2016/02/13/…
Alex Theedom

Réponses:

720

En supposant ici que vous faites référence aux javax.inject.Injectannotations. @Injectfait partie de la norme Java CDI ( Contexts and Dependency Injection ) introduite dans Java EE 6 (JSR-299), en savoir plus . Spring a choisi de soutenir l'utilisation @Injectsynonyme de leur propre@Autowired annotation.

Donc, pour répondre à votre question, @Autowiredc'est la propre annotation de Spring. @Injectfait partie d'une nouvelle technologie Java appelée CDI qui définit une norme d'injection de dépendances similaire à Spring. Dans une application Spring, les deux annotations fonctionnent de la même manière que Spring a décidé de prendre en charge certaines annotations JSR-299 en plus des leurs.

bouillie
la source
115
Donc en théorie, si vous utilisiez @Inject, vous pourriez remplacer spring par un autre framework DI par exemple Guice et injecter vos dépendances de la même manière.
Alex Barnes du
71
Au risque d'être pédant: @Injectest un JSR (JSR-330) distinct du CDI (JSR-299).
Brad Cupit
36
Si vous ne comptez que sur les annotations JSR- *, bien sûr, vous pouvez remplacer votre framework DI. Mais voulez-vous? Une fois que vous avez commencé à utiliser le printemps, il est probable que vous en ayez utilisé beaucoup plus que la simple DI. Vous ne ferez pas seulement un changement; et même si vous le faites, ce ne sont pas quelques recherches et remplacements qui vont faire ou défaire le mouvement. D'un autre côté, les propres annotations de Spring vous offrent beaucoup plus de fonctionnalités. Maîtriser un bon cadre vous en donnera plus que difficilement.
Agoston Horvath
18
Je suis d'accord avec vous que nous ne changeons pas souvent les cadres DI. Cependant, si notre code source a plusieurs packages et si vous souhaitez créer un package commun que vous souhaitez partager entre plusieurs projets, puis @Injectutiliser l'annotation JSR est préférable à l'utilisation @Autowiredqui verrouille votre base de code avec Spring DI.
Aditya
3
L'utilisation @Injectseule ne garantit pas l'indépendance du framework. Vous devez également déclarer des beans injectables sans mécanismes dépendants du framework comme Spring @Componentou or application.xml, mais utilisez @Namedet @Singletonau niveau de la classe. Aucune idée si un projet Spring déclare vraiment des haricots comme ça aujourd'hui - je n'ai même jamais entendu parler d'un projet qui a migré de Spring vers JEE ...
Marcus K.
162

Voici un article de blog qui compare @Resource, @Injectet @Autowired, et semble faire un travail assez complet.

Depuis le lien:

À l'exception des tests 2 et 7, la configuration et les résultats étaient identiques. Lorsque j'ai regardé sous le capot, j'ai déterminé que les annotations «@Autowired» et «@Inject» se comportaient de manière identique. Ces deux annotations utilisent le 'AutowiredAnnotationBeanPostProcessor' pour injecter des dépendances. '@Autowired' et '@Inject' peuvent être utilisés de manière interchangeable pour injecter des grains de printemps. Cependant, l'annotation '@Resource' utilise le 'CommonAnnotationBeanPostProcessor' pour injecter les dépendances. Même s'ils utilisent différentes classes de post-processeur, ils se comportent tous de façon presque identique. Vous trouverez ci-dessous un résumé de leurs chemins d'exécution.

Tests 2 et 7 auxquels l'auteur fait référence respectivement «injection par nom de champ» et «tentative de résolution d'un bean en utilisant un mauvais qualificatif».

La conclusion devrait vous donner toutes les informations dont vous avez besoin.

nicholas.hauschild
la source
4
Cet article est une excellente explication des trois annotations. J'ai dû le relire après le premier coup; mais, un excellent article.
Thomas
1
Merci beaucoup! L'article a répondu à plusieurs de mes réponses dans ma recherche de trouver les différences et les similitudes entre Spring et JavaEE, ainsi que quelques autres questions que j'avais.
Kevin Cruijssen
36

Pour gérer la situation dans laquelle il n'y a pas de câblage, les beans sont disponibles avec l' @Autowired requiredattribut défini sur false.

Mais lors de l'utilisation @Inject, l'interface du fournisseur fonctionne avec le bean, ce qui signifie que le bean n'est pas injecté directement mais avec le fournisseur.

amits
la source
8
Ceci est si important et a été ignoré dans les réponses les plus votées.
Igor Donin
Par défaut, le paramètre requis est défini sur true pour Autowired. Réf: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
tranquille
25

À partir du printemps 3.0, offres de printemps pour soutenir JSR-330 annotations d'injection de dépendance ( @Inject, @Named,@Singleton ).

Il existe une section distincte dans la documentation Spring à leur sujet, y compris des comparaisons avec leurs équivalents Spring.

Andre Steingress
la source
Question ici, que voulez-vous dire lorsque vous dites que Spring prend en charge JSR? Le conteneur ne prend-il pas en charge JSR indépendamment de Spring et exige-t-il que le conteneur soit conforme à J2EE? Voulez-vous dire qu'il enveloppe la fonctionnalité? Si Spring ne le "supportait" pas, l'annotation de javax ne fonctionnerait-elle toujours pas par défaut?
Dan Chase
Il n'est pas indispensable d'exécuter Spring dans un conteneur JEE, vous pouvez également l'utiliser dans un conteneur de servlet / JSP comme Tomcat et avoir toujours le support JSR-330. Spring est un conteneur DI distinct, il n'échange pas les beans CDI avec le serveur JEE hôte si c'est ce que vous voulez dire. Vous pouvez utiliser CDI dans un conteneur JEE ou Spring beans - mais vous ne pouvez pas utiliser les deux (hors de la boîte).
Andre Steingress
22

La principale différence (remarquée lors de la lecture des documents Spring ) entre @Autowiredet @Injectest que, @Autowireda l'attribut «requis» tandis que @Inject n'a pas d'attribut «requis».

Chanceux
la source
que voulez-vous dire par requis?
mattyman
2
@mattymanme D'après les documents, "Par défaut, le câblage automatique échoue chaque fois que aucun bean candidat n'est disponible; le comportement par défaut consiste à traiter les méthodes, constructeurs et champs annotés comme indiquant les dépendances requises. Ce comportement peut être modifié en définissant l'attribut requis sur false ". Par exemple @Autowired(required=false):. En termes simples, "L' requiredattribut indique que la propriété n'est pas requise à des fins de câblage automatique, la propriété est ignorée si elle ne peut pas être câblée automatiquement."
Lucky
regardez dans le code source de l'interface publique Autowired {/ ** * Déclare si la dépendance annotée est requise. * / boolean required () par défaut true; } interface publique Inject {}
tarn
15

Mieux utiliser @Inject tout le temps. Parce que c'est l'approche de configuration java (fournie par sun) qui rend notre application indépendante du framework. Donc, si vous ressortez aussi, vos cours fonctionneront.

Si vous utilisez @Autowired, cela ne fonctionnera qu'avec le ressort car @Autowired est une annotation fournie par le ressort.

tech.yenduri
la source
13
Le soleil est mort. Vive le soleil.
Amrinder Arora
6
à quelle fréquence allez-vous changer le cadre? juste curieux
Kay
Sur la plupart des projets, j'ai vu Autowired plutôt que Inject. Je comprends la justification de la réponse mais je ne peux pas voter.
Witold Kaczurba
13

@Autowired l'annotation est définie dans le framework Spring.

@Injectannotation est une annotation standard, qui est définie dans le standard "Dependency Injection for Java" (JSR-330) . Spring (depuis la version 3.0) prend en charge le modèle généralisé d'injection de dépendances qui est défini dans la norme JSR-330. ( Les frameworks Google Guice et Picocontainer prennent également en charge ce modèle).

Avec @Injectpeut être injecté la référence à l'implémentation de l' Providerinterface, ce qui permet d'injecter les références différées.

Les annotations @Injectet @Autowired- sont des analogies presque complètes. Outre l' @Autowiredannotation, l' @Injectannotation peut être utilisée pour les propriétés de liaison automatique, les méthodes et les constructeurs.

Contrairement à l' @Autowiredannotation, l' @Injectannotation n'a pas d' requiredattribut. Par conséquent, si les dépendances ne sont pas trouvées, une exception sera levée.

Il existe également des différences dans les clarifications des propriétés de liaison. S'il y a ambiguïté dans le choix des composants pour l'injection, le @Namedqualificatif doit être ajouté. Dans une situation similaire pour l' @Autowiredannotation sera ajouté un @Qualifierqualificatif (JSR-330 définit sa propre @Qualifierannotation et via cette annotation qualificative @Namedest définie).

Arash
la source
Même si '@Inject' n'a pas d'attribut requis, l'état de Java Docs: l'injection des membres annotés avec '@Inject' est requise. Ce qui semble impliquer que si un membre n'est pas trouvé, son injection échouera. Voir Java Docs: docs.oracle.com/javaee/7/api/javax/inject/Inject.html
Alex Theedom
12

@Inject n'a pas d'attribut «requis»

Mykhaylo Adamovych
la source
12

En plus de ce qui précède:

  1. La portée par défaut pour les @Autowiredbeans est Singleton alors qu'en utilisant l' @Injectannotation JSR 330, c'est comme le prototype de Spring .
  2. Il n'y a pas d'équivalent de @Lazy dans JSR 330 utilisant @Inject.
  3. Il n'y a pas d'équivalent de @Value dans JSR 330 en utilisant @Inject.
Keyur Vyas
la source
0

L' @Injectannotation fait partie de la collection d'annotations JSR-330. Il s'agit des chemins d'exécution Correspondance par type, Correspondance par qualificatif, Correspondance par nom. Ces chemins d'exécution sont valables pour l'injection de setter et de champ. Le comportement de l' @Autowiredannotation est le même que celui de l' @Injectannotation. La seule différence est que l' @Autowiredannotation fait partie du framework Spring. @Autowiredl'annotation a également les chemins d'exécution ci-dessus. Je recommande donc le @Autowiredpour votre réponse.

Kushani5j
la source