Devo usar @EJB ou @Inject

148

Eu encontrei esta pergunta: Qual é a diferença entre @Inject e @EJB, mas eu não fiquei mais sábio. Eu não havia feito o Java EE antes nem tenho experiência com injeção de dependência, portanto não entendo o que devo usar?

@EJB é uma maneira antiga de injetar? A injeção feita pelo contêiner EJB ao usar esta anotação durante o uso do @Inject usa a nova estrutura CDI? Essa é a diferença e devo usar o @Inject em vez do @EJB, se este for o caso?

LuckyLuke
fonte

Respostas:

178

O @EJBé usado para injetar apenas EJBs e está disponível há algum tempo. @Injectpode injetar qualquer bean gerenciado e faz parte da nova especificação CDI (desde o Java EE 6).

Em casos simples, você pode simplesmente mudar @EJBpara @Inject. Em casos mais avançados (por exemplo, quando você depende muito @EJBdos atributos de beanName, como , lookupou beanInterface) do que para usá- @Injectlo, você precisa definir um @Producercampo ou método.

Esses recursos podem ser úteis para entender as diferenças entre @EJBe @Producese como obter o melhor deles:

Blog de Antonio Goncalves:
CDI Parte I
CDI Parte II
CDI Parte III

Documentação do JBoss Weld:
CDI e o ecossistema Java EE

StackOverflow:
Injete o feijão @EJB com base nas condições

Piotr Nowicki
fonte
4
por que @EJBfunciona para injeção circular (um feijão singleton e outro feijão precisando de uma referência um para o outro)? (com referência a minha resposta abaixo - eu não tenho certeza se estou fazendo a coisa certa ao mudar para @EJB)
necromante
2
porque você não está injetando a implementação, mas um proxy que se interpõe na implementação. por isso, você obtém as vantagens de "ligação tardia" e outros recursos de contêiner.
ele
33

@Injectpode injetar qualquer bean, enquanto @EJBsó pode injetar EJBs. Você pode usar para injetar EJBs, mas eu preferiria em @Injectqualquer lugar.

Bozho
fonte
1
O que exatamente faz a injeção quando usamos o @Inject? O contêiner JavaEE? Pode injetar POJO 's?
Koray Tugay
3
com CDI é o recipiente CDI (fornecido no recipiente JavaEE)
Bozho
16

Atualização: Esta resposta pode estar incorreta ou desatualizada. Veja os comentários para obter detalhes.

Eu mudei de @Injectpara @EJBporque @EJBpermite injeção circular enquanto @Injectvomita.

Detalhes: eu precisava @PostConstructchamar um @Asynchronousmétodo, mas o faria de forma síncrona. A única maneira de fazer a chamada assíncrona era fazer com que a chamada original fosse um método de outro bean e retornasse o método do bean original. Para fazer isso, cada feijão precisava de uma referência ao outro - portanto circular. @Injectfalhou nesta tarefa enquanto @EJBfuncionava.

necromante
fonte
@MartijnBurger Não tenho o código à mão, nem um ambiente Java EE à mão. Basta criar 2 classes Java e @Injectelas nos campos públicos uma da outra. Se isso funcionar, então minha resposta está errada. Se isso não funcionar, minha resposta está correta até agora. Em seguida, mude @Injectpara @EJB(e, possivelmente, anote as próprias classes? Eu esqueço.). Então a injeção mútua cíclica deve funcionar bem. Por isso mudei @Injectpara @EJB. Espero que isso faça sentido.
Necromancer
Criei dois pojo e injetei o pojo um no outro. Funciona sem problemas na minha configuração (JBoss Application Server 8.2 = CDI 1.2)
Martijn Burger
1
Obrigado @MartijnBurger, vou confirmar isso e, enquanto isso, adicione uma nota de cautela à minha resposta.
Necromancer
Não sabe exatamente o que você queria alcançar, mas isso provavelmente faz exatamente o que você deseja e sem uma dependência circular. tomee.apache.org/examples-trunk/async-postconstruct/README.html . Também eventos CDI assíncronos podem ser um caminho mais limpo (dependendo dos requisitos).
JanM 5/15
12

Aqui está uma boa discussão sobre o tópico. Gavin King recomenda @Inject sobre @EJB para EJBs não remotos.

http://www.seamframework.org/107780.lace

ou

https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace

Re: Injetar com @EJB ou @Inject?

  1. Nov 2009, 20:48 America / New_York | Link Gavin King

Esse erro é muito estranho, pois as referências locais do EJB sempre devem ser serializáveis. Bug em glassfish, talvez?

Basicamente, o @Inject é sempre melhor, pois:

it is more typesafe,
it supports @Alternatives, and
it is aware of the scope of the injected object.

Eu recomendo o uso do @EJB, exceto para declarar referências a EJBs remotos.

e

Re: Injetar com @EJB ou @Inject?

  1. Nov 2009, 17:42 America / New_York | Link Gavin King

    Significa @EJB melhor com EJBs remotos?

Para um EJB remoto, não podemos declarar metadados como qualificadores, @Alternative, etc, na classe bean, pois o cliente simplesmente não terá acesso a esses metadados. Além disso, alguns metadados adicionais devem ser especificados que não são necessários para o caso local (nome JNDI global de qualquer que seja). Então, tudo isso precisa ir para outro lugar: a declaração @Produces.

John Manko
fonte
1
Embora isso possa teoricamente responder à pergunta, seria preferível incluir aqui as partes essenciais da resposta e fornecer o link para referência. Dessa forma, essa resposta seria valiosa agora mesmo quando o link estiver inoperante.
Mifeet
4

Também pode ser útil entender a diferença em termos de Identidade do Bean de Sessão ao usar @EJB e @Inject. De acordo com as especificações, o código a seguir será sempre true:

@EJB Cart cart1;
@EJB Cart cart2;
 if (cart1.equals(cart2)) { // this test must return true ...}

Usar @Inject em vez de @EJB não é o mesmo.

consulte também a identidade dos beans de sessão sem estado para obter mais informações

ken
fonte
0

A injeção já existia no Java EE 5 com as anotações @Resource, @PersistentUnit ou @EJB, por exemplo. Mas estava limitado a certos recursos (fonte de dados, EJB...) E a certos componentes (Servlets, EJBs, JSF backing bean...). Com o CDI, você pode injetar praticamente qualquer coisa em qualquer lugar, graças à anotação @Inject.

javierZanetti
fonte