Qual anotação, @Resource ( jsr250 ) ou @Autowired (específico da Primavera) devo usar no DI?
Eu usei com sucesso tanto no passado @Resource(name="blah")
quanto@Autowired @Qualifier("blah")
Meu instinto é ficar com a @Resource
etiqueta, uma vez que foi ratificada pelo povo jsr.
Alguém tem pensamentos fortes sobre isso?
Respostas:
Na primavera pré-3.0, não importa qual.
Na primavera 3.0, há suporte para a anotação padrão ( JSR-330 )
@javax.inject.Inject
- use-a com uma combinação de@Qualifier
. Observe que o spring agora também suporta a@javax.inject.Qualifier
meta-anotação:Então você pode ter
ou
E depois:
Isso faz menos uso de nomes de string, que podem ser digitados incorretamente e são mais difíceis de manter.
Quanto à pergunta original: ambos, sem especificar nenhum atributo da anotação, executam a injeção por tipo. A diferença é:
@Resource
permite que você especifique um nome do feijão injetado@Autowired
permite marcar como não obrigatório.fonte
foo
ou de um construtorSomeBean
com umFoo
parâmetro?@Resource
e@Autowired
, a resposta real é a postada por @Ichthyo, acho que essa deve ser atualizada.Ambos
@Autowired
(ou@Inject
) e@Resource
funcionam igualmente bem. Mas há uma diferença conceitual ou uma diferença no significado@Resource
significa obter um recurso conhecido por nome . O nome é extraído do nome do setter ou campo anotado ou do nome-Parameter.@Inject
ou@Autowired
tente conectar um outro componente adequado por tipo .Então, basicamente, esses são dois conceitos bastante distintos. Infelizmente, o Spring-Implementation of
@Resource
possui um fallback interno, que entra em ação quando a resolução por nome falha. Nesse caso, ele volta ao@Autowired
tipo de resolução do tipo. Embora esse fallback seja conveniente, IMHO causa muita confusão, porque as pessoas desconhecem a diferença conceitual e tendem a usar@Resource
para a fiação automática baseada em tipo.fonte
@Resource
campo anotado e o nome do campo corresponder ao ID de um bean no contêiner, o Spring lançaráorg.springframework.beans.factory.BeanNotOfRequiredTypeException
se seus tipos diferirem - isso ocorre porque os grãos são correspondidos primeiro pelo nome na@Resource
anotação, não pelo tipo. Mas se o nome da propriedade não corresponder ao nome do bean, o Spring os conectará por tipo.@Autowire
não pode e não funciona. Você terá que usar@Resource
nesse caso.A principal diferença é que
@Autowired
é uma anotação de primavera. Considerando que@Resource
é especificado pelo JSR-250, como você apontou. Portanto, o último faz parte do Java, enquanto o primeiro é específico do Spring.Portanto, você está certo ao sugerir isso, em certo sentido. Eu encontrei pessoas usam
@Autowired
com@Qualifier
porque é mais poderoso. Mudar de uma estrutura para outra é considerado muito improvável, se não um mito, especialmente no caso da primavera.fonte
@Autowired
com@Qualifier
realmente é mais poderoso do que o padrão JSR@Resource
anotação (pense em dependências opcionais, por exemplo, com@Autowired(required=false)
. Você não pode fazer isso com@Resource
)Gostaria de enfatizar um comentário de @Jules sobre esta resposta a esta pergunta. O comentário traz um link útil: Injeção de mola com @Resource, @Autowired e @Inject . Convido você a lê-lo por inteiro, no entanto, aqui está um rápido resumo de sua utilidade:
Como as anotações selecionam a implementação correta?
@Autowired
e@Inject
@Resource
Quais anotações (ou combinação de) devo usar para injetar meus beans?
Nomeie explicitamente seu componente [@Component ("beanName")]
Use
@Resource
com oname
atributo [@Resource (name = "beanName")]Por que não devo usar
@Qualifier
?Evite
@Qualifier
anotações, a menos que deseje criar uma lista de beans semelhantes. Por exemplo, você pode marcar um conjunto de regras com uma@Qualifier
anotação específica . Essa abordagem simplifica a injeção de um grupo de classes de regra em uma lista que pode ser usada para o processamento de dados.A injeção de feijão atrasa meu programa?
Examine pacotes específicos em busca de componentes
[context:component-scan base-package="com.sourceallies.person"]
. Embora isso resulte em maiscomponent-scan
configurações, reduz a chance de adicionar componentes desnecessários ao seu contexto do Spring.Referência: injeção de mola com @Resource, @Autowired e @Inject
fonte
Foi o que obtive do Manual de Referência do Spring 3.0.x : -
fonte
O @Autowired + @Qualifier funcionará apenas com o DI de mola, se você quiser usar outro DI no futuro. @Resource é uma boa opção.
outra diferença que achei muito significativa é que o @Qualifier não suporta a fiação dinâmica do bean, pois o @Qualifier não suporta espaço reservado, enquanto o @Resource o faz muito bem.
Por exemplo: se você tiver uma interface com várias implementações como esta
com @Autowired e @Qualifier, você precisa definir uma implementação filho específica, como
que não fornece espaço reservado enquanto estiver com @Resource, você pode colocar espaço reservado e usar o arquivo de propriedades para injetar uma implementação filho específica, como
em que service.name está definido no arquivo de propriedades como
Espero que ajude alguém :)
fonte
Ambos são igualmente bons. A vantagem de usar o recurso é no futuro, se você quiser outra estrutura de DI diferente da primavera, suas alterações de código serão muito mais simples. Usando o Autowired, seu código está fortemente acoplado às molas DI.
fonte
Ao analisar criticamente a partir das classes base dessas duas anotações, você perceberá as seguintes diferenças.
@Autowired
usaAutowiredAnnotationBeanPostProcessor
para injetar dependências.@Resource
usaCommonAnnotationBeanPostProcessor
para injetar dependências.Embora eles usem classes de pós-processador diferentes, todos se comportam quase de forma idêntica. As diferenças estão criticamente em seus caminhos de execução, que destacamos abaixo.
1.Matches por tipo
2.Restricts por Qualifiers
3.Matches por nome
1. Correspondências por nome
2. Correspondências por tipo
3. Restrições por qualificadores (ignoradas se a correspondência for encontrada por nome)
fonte
Com a
@Resource
auto-injeção do bean, pode ser necessário executar toda a lógica extra adicionada pelos processadores pós-bean, como coisas relacionadas a transações ou segurança.Com o Spring 4.3+
@Autowired
também é capaz de fazer isso.fonte
@Resource
é frequentemente usado por objetos de alto nível, definidos via JNDI.@Autowired
ou@Inject
será usado por feijões mais comuns.Até onde eu sei, não é uma especificação, nem mesmo uma convenção. É mais a maneira lógica do código padrão usar essas anotações.
fonte
Como uma observação aqui:
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext
eSpringBeanAutowiringSupport.processInjectionBasedOnServletContext
NÃO funciona com@Resource
anotação. Então, há diferença.fonte