Qual é a diferença entre @Inject e @Autowired no Spring Framework? Qual usar sob que condição?

695

Estou passando por alguns blogs no SpringSource e em um dos blogs, o autor está usando @Injecte suponho que ele também possa usar @Autowired.

Aqui está o trecho de código:

@Inject private CustomerOrderService customerOrderService;

Não tenho certeza sobre a diferença entre @Injecte @Autowiredgostaria que alguém explicasse sua diferença e qual usar em que situação?

Rachel
fonte
3
Eu não tenho uma resposta, já que também sou novo nisso, mas isso pode ajudar sakaenakajima.wordpress.com/2010/08/10/…
Sagar V
2
A diferença entre '@Inject' e '@Autowired' é explicada bem neste artigo alextheedom.wordpress.com/2016/02/13/…
Alex Theedom

Respostas:

719

Supondo que você esteja se referindo às javax.inject.Injectanotações. @Injectfaz parte do padrão Java CDI ( Contextos e Injeção de Dependências ) introduzido no Java EE 6 (JSR-299), leia mais . O Spring optou por oferecer suporte ao uso de @Injectsinônimos com sua própria @Autowiredanotação.

Portanto, para responder sua pergunta, @Autowiredé a anotação da própria Spring. @Injectfaz parte de uma nova tecnologia Java chamada CDI que define um padrão para injeção de dependência semelhante ao Spring. Em um aplicativo Spring, as duas anotações funcionam da mesma maneira que o Spring decidiu suportar algumas anotações do JSR-299, além das próprias.

pap
fonte
115
Portanto, em teoria, se você usasse o @Inject, poderia substituir a primavera por outra estrutura de DI, por exemplo, Guice e injetar suas dependências da mesma maneira.
Alex Barnes
71
Correndo o risco de ser pedante: @Injecté um JSR separado (JSR-330) do CDI (JSR-299).
Brad Cupit
36
Se você confiar apenas nas anotações JSR- *, certamente poderá substituir sua estrutura de DI. Mas você vai? Depois de começar a usar a primavera, é provável que você tenha usado muito mais do que apenas o DI. Você não fará apenas uma alteração; e mesmo que você faça isso, não são poucas as pesquisas e substituições que farão ou serão interrompidas. Por outro lado, as anotações do Spring oferecem muito mais funcionalidade. Dominar uma boa estrutura lhe dará mais do que dificilmente usar muitas.
Agoston Horvath
18
Eu concordo com você que não mudamos as estruturas de DI frequentemente. No entanto, se nosso código-fonte tiver vários pacotes e se você deseja criar um pacote comum que deseja compartilhar em vários projetos e, em seguida, seguir a @Injectanotação JSR, é melhor do que usar o @Autowiredque bloqueia sua base de código com DI de primavera.
Aditya
3
Usar @Injectsozinho não garante a independência da estrutura. Você também precisaria declarar beans injetáveis ​​sem mecanismos dependentes da estrutura, como Spring, @Componentou application.xml, mas use @Namede @Singletonno nível de classe. Não faço ideia se algum projeto Spring realmente declara feijão como esse hoje - eu mesmo nunca ouvi falar de qualquer projecto que migraram da Primavera para JEE ...
Marcus K.
162

Aqui está um post que compara @Resource, @Injecte @Autowired, e parece fazer um trabalho bastante abrangente.

No link:

Com exceção dos testes 2 e 7, a configuração e os resultados foram idênticos. Quando olhei por baixo do capô, determinei que as anotações '@Autowired' e '@Inject' se comportam de forma idêntica. Ambas as anotações usam o 'AutowiredAnnotationBeanPostProcessor' para injetar dependências. '@Autowired' e '@Inject' podem ser usados ​​intercambiáveis ​​para injetar beans Spring. No entanto, a anotação '@Resource' usa o 'CommonAnnotationBeanPostProcessor' para injetar dependências. Embora eles usem diferentes classes de pós-processador, todos eles se comportam quase de forma idêntica. Abaixo está um resumo de seus caminhos de execução.

Os testes 2 e 7 que o autor faz referência são 'injeção pelo nome do campo' e 'uma tentativa de resolver um bean usando um qualificador incorreto', respectivamente.

A conclusão deve fornecer todas as informações necessárias.

nicholas.hauschild
fonte
4
Esse artigo é uma ótima explicação para as três anotações. Eu tive que relê-lo após o primeiro golpe; mas, um excelente artigo.
Thomas
1
Muito obrigado! O artigo respondeu várias das minhas respostas na minha busca de encontrar as diferenças e semelhanças entre Spring e JavaEE, bem como algumas outras perguntas que eu tinha.
18716 Kevin Murrijssen
36

Para lidar com a situação em que não há fiação, os beans estão disponíveis com o @Autowired requiredatributo definido como false.

Porém, ao usar @Inject, a interface do provedor trabalha com o bean, o que significa que o bean não é injetado diretamente, mas com o provedor.

amits
fonte
8
Isso é muito importante e foi esquecido nas respostas mais votadas.
Igor Donin
Por padrão, o parâmetro necessário é definido como true para Ligação automática. Ref: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
tranquilo
25

Como de mola 3.0, ofertas mola de suporte para JSR-330 anotações injecção dependência ( @Inject, @Named, @Singleton).

Há uma seção separada na documentação do Spring sobre eles, incluindo comparações com seus equivalentes do Spring.

Andre Steingress
fonte
Pergunta aqui, o que você quer dizer quando diz que o Spring suporta JSR? O contêiner não suporta JSR independente do Spring e um requisito para que o contêiner seja compatível com J2EE? Você quer dizer que envolve a funcionalidade? Se o Spring não o "suportasse", a anotação do javax ainda não funcionaria por padrão?
Dan perseguição
Não é necessário executar o Spring em um contêiner JEE, você também pode usá-lo em um contêiner servlet / JSP como o Tomcat e ainda ter o suporte ao JSR-330. Spring é um contêiner DI separado, não "intercambia" beans CDI com o servidor JEE host, se é isso que você quer dizer. Você pode usar CDI em um contêiner JEE ou Spring beans - mas não pode usar os dois (fora da caixa).
Andre Steingress
22

A principal diferença (observada ao ler o Spring Docs ) entre @Autowirede @Injecté que, @Autowiredpossui o atributo 'required' enquanto o @Inject não possui o atributo 'required'.

Por sorte
fonte
o que você quer dizer com obrigatório?
mattyman
2
@mattymanme Nos documentos, "Por padrão, a fiação automática falha sempre que nenhum bean candidato estiver disponível; o comportamento padrão é tratar métodos, construtores e campos anotados como indicando dependências necessárias. Esse comportamento pode ser alterado definindo o atributo necessário como false " Por exemplo:. @Autowired(required=false)Em termos simples, "O requiredatributo indica que a propriedade não é necessária para fins de conexão automática, a propriedade será ignorada se não puder ser conectada automaticamente".
Sorte
procure na interface pública do código-fonte Autowired {/ ** * Declara se a dependência anotada é necessária. * / boolean required () default true; } interface pública Injetar {}
tarn
15

Melhor usar @Inject o tempo todo. Porque é a abordagem de configuração java (fornecida pela sun) que torna nosso aplicativo independente do framework. Então, se você saltar também, suas aulas funcionarão.

Se você usar @Autowired, ele funcionará apenas com a primavera, porque @Autowired é uma anotação fornecida pela primavera.

tech.yenduri
fonte
13
O sol está morto. Viva o sol.
Amrinder Arora
6
com que frequência você vai mudar a estrutura? apenas curioso
Kay
Na maioria dos projetos, vi Autowired em vez de Injetar. Entendo a lógica da resposta, mas não posso votar.
Witold Kaczurba 23/03
13

@Autowired anotação é definida na estrutura do Spring.

@Injectanotação é uma anotação padrão, definida no padrão "Injeção de Dependência para Java" (JSR-330) . O Spring (desde a versão 3.0) suporta o modelo generalizado de injeção de dependência, definido no padrão JSR-330. ( As estruturas do Google Guice e a estrutura do Picocontainer também suportam esse modelo).

Com @Injectpode ser injetada a referência à implementação da Providerinterface, o que permite injetar as referências adiadas.

Anotações @Injecte @Autowired- é quase analogias completas. Assim como a @Autowiredanotação, a @Injectanotação pode ser usada para propriedades, métodos e construtores de ligação automática.

Ao contrário da @Autowiredanotação, a @Injectanotação não tem requiredatributo. Portanto, se as dependências não forem encontradas - será lançada uma exceção.

Há também diferenças nos esclarecimentos das propriedades de ligação. Se houver ambiguidade na escolha dos componentes para a injeção, o @Namedqualificador deve ser adicionado. Em uma situação semelhante para @Autowiredanotação, será adicionado um @Qualifierqualificador (o JSR-330 define sua própria @Qualifieranotação e, através dessa anotação de qualificador, @Namedestá definido).

Arash
fonte
Mesmo que o '@Inject' não tenha um atributo obrigatório, o estado do Java Docs: É necessária a injeção de membros anotados com '@Inject'. O que parece implicar que, se um membro não for encontrado, seu injetor falhará. Consulte Java Docs: docs.oracle.com/javaee/7/api/javax/inject/Inject.html
Alex Theedom
12

@Inject não possui atributo 'obrigatório'

Mykhaylo Adamovych
fonte
12

Além do acima:

  1. O escopo padrão para @Autowiredbeans é Singleton, enquanto o uso da @Injectanotação JSR 330 é como o protótipo do Spring .
  2. Não há equivalente a @Lazy no JSR 330 usando @Inject.
  3. Não há equivalente a @Value no JSR 330 usando @Inject.
Keyur Vyas
fonte
0

A @Injectanotação é uma das coleções de anotações JSR-330. Isso tem caminhos de execução de Correspondência por tipo, Correspondência por qualificador, Correspondência por nome. Esses caminhos de execução são válidos para injeção de setter e campo. O comportamento da @Autowiredanotação é o mesmo da @Injectanotação. A única diferença é que a @Autowiredanotação faz parte da estrutura do Spring. @AutowiredA anotação também possui os caminhos de execução acima. Então, eu recomendo a @Autowiredsua resposta.

Kushani5j
fonte