Como CDI e EJB se comparam? interagir?

106

Estou tendo dificuldade em entender como os dois interagem e onde está o limite entre eles. Eles se sobrepõem? Existem redundâncias entre eles?

Sei que há anotações associadas a ambos, mas não consegui encontrar uma lista completa de ambos com breves descrições. Não tenho certeza se isso ajudaria a esclarecer como eles diferem ou onde se sobrepõem.

Realmente apenas confuso. Eu (acho que) entendo o EJB razoavelmente bem, acho que estou tendo dificuldade em entender exatamente o que o CDI traz para a mesa e como ele suplanta ou aprimora o que o EJB já oferece.

Tim
fonte
3
Esta pergunta está no topo da pesquisa do Google por "diferença de EJB CDI", mas encontrei a resposta em stackoverflow.com/questions/13487987/… mais claro
matt freake

Respostas:

50

CDI: trata-se de injeção de dependência. Isso significa que você pode injetar a implementação da interface em qualquer lugar. Este objeto pode ser qualquer coisa, não pode estar relacionado ao EJB. Aqui está um exemplo de como injetar um gerador aleatório usando CDI. Não há nada sobre EJB. Você usará o CDI quando quiser injetar serviços não-EJB, diferentes implementações ou algoritmos (portanto, você não precisa do EJB lá).
EJB: você entende, e provavelmente está confuso com a @EJBanotação - ela permite que você injete implementação em seu serviço ou qualquer outra coisa. A ideia principal é que a classe, onde você injeta, seja gerenciada pelo container EJB. Parece que o CDI entende o que é EJB, portanto, no servidor compatível com Java EE 6, em seu servlet você pode escrever ambos

@EJB EJBService ejbService;

e

@Inject EJBService ejbService;

isso é o que pode deixá-lo confuso, mas provavelmente é a única coisa que é a ponte entre o EJB e o CDI.

Quando estamos falando sobre CDI, você pode injetar outros objetos em classes gerenciadas por CDI (eles apenas devem ser criados por estruturas compatíveis com CDI).

O que mais o CDI oferece ... Por exemplo, você usa Struts 2 como framework MVC (apenas exemplo), e você está limitado aqui, mesmo usando EJB 3.1 - você não pode usar @EJBanotação na ação do Struts, não é gerenciado por container. Mas quando você adiciona o plug-in Struts2-CDI, pode escrever ali uma @Injectanotação para a mesma coisa (de forma que não seja necessária mais pesquisa JNDI). Desta forma, aumenta a potência do EJB, mas como mencionei antes, o que você injeta com CDI - não importa se está relacionado ao EJB ou não, e esse é o poder.

PS. link atualizado para o exemplo

Maxym
fonte
@EJB e @Inject são realmente equivalentes funcionalmente? Acho que foi a sobreposição de métodos de injeção entre o CDI e parte do resto da sopa de acrônimos Java EE que me confundiu. Mais leituras parecem indicar que há esperança de alinhar as anotações.
Tim de
@Maxym Quando você usa @ Inject, como você pode garantir que @ Stateless ou qualquer outro componente do lado do servidor do EJB ainda use recursos como pooling ou simultaneidade que é oferecido pelo contêiner. Espero que isso não seja oferecido pelo CDI certo?
Bala
1
@Bala: CDI não oferece pooling ... olhe para CDI com ou sem EJB3.1 , espero que ele responda sua pergunta ..
Maxym
@KorayTugay: CDI é um recurso Java EE, então qualquer servidor compatível com Java EE 6 tem (Glassfish 3.0.1+ não se engana, JBoss 6+ etc.) Você pode dar uma olhada no JBoss Weld, uma implementação CDI de referência que você pode usar por exemplo Tomcat ...
Maxym
191

Atualmente é um pouco confuso, pois agora existem vários modelos de componentes em Java EE. Eles são CDI , EJB3 e JSF Managed Beans .

CDI é o novo garoto do bairro. Feijão CDI apresentam dependency injection, scopinge um event bus. Os beans CDI são os mais flexíveis em relação à injeção e ao escopo. O barramento de eventos é muito leve e muito adequado até mesmo para os aplicativos da web mais simples. Além disso, o CDI também expõe um recurso muito avançado chamado portable extensions, que é uma espécie de mecanismo de plug-in para fornecedores para fornecer funcionalidade extra para Java EE que pode ser disponibilizada em todas as implementações (Glassfish, JBoss AS, Websphere, etc) .

Os beans EJB3 foram adaptados do antigo modelo de componente EJB2 legado * e foram os primeiros beans em Java EE a serem beans gerenciados por meio de uma anotação. Apresentam beans EJB3 dependency injection, declarative transactions, declarative security, pooling, concurrency control, asynchronous executione remoting.

A injeção de dependência em beans EJB3 não é tão flexível quanto em beans CDI e os beans EJB3 não têm conceito de escopo. No entanto, os beans EJB3 são transacionais e agrupados por padrão ** , duas coisas muito úteis que o CDI optou por deixar no domínio do EJB3. Os demais itens citados também não estão disponíveis no CDI. No entanto, o EJB3 não possui barramento de eventos próprio, mas possui um tipo especial de bean para ouvir mensagens; o bean acionado por mensagem. Isso pode ser usado para receber mensagens do Java Messaging System ou de qualquer outro sistema que tenha um adaptador de recursos JCA. O uso de mensagens completas para eventos simples é muito mais pesado do que o barramento de eventos CDI e o EJB3 define apenas um ouvinte, não uma API de produtor.

JSF Managed Beans existem no Java EE desde que o JSF foi incluído. Eles também apresentam dependency injectione scoping. O JSF Managed Beans introduziu o conceito de escopo declarativo. Originalmente, os escopos eram bastante limitados e na mesma versão do Java EE em que os beans EJB3 já podiam ser declarados por meio de anotações, os JSF Managed Beans ainda tinham que ser declarados em XML. A versão atual do JSF Managed Beans também é finalmente declarada por meio de uma anotação e os escopos são expandidos com um escopo de visualização e a capacidade de criar escopos personalizados. O escopo da visualização, que lembra os dados entre as solicitações para a mesma página, é um recurso exclusivo do JSF Managed Beans.

Além do escopo de visão, há muito pouco ainda acontecendo para JSF Managed Beans no Java EE 6. O escopo de visão ausente no CDI é lamentável, pois caso contrário, o CDI teria sido um superconjunto perfeito do que o JSF Managed Beans oferece. Atualização : No Java EE 7 / JSF 2.2, um @ViewScoped compatível com CDI foi adicionado, tornando o CDI um superconjunto perfeito. Atualização 2 : No JSF2.3, os beans gerenciados JSF foram preteridos em favor dos beans gerenciados CDI.

Com EJB3 e CDI a situação não é tão clara. O modelo de componente EJB3 e a API oferecem muitos serviços que o CDI não oferece, portanto, normalmente, o EJB3 não pode ser substituído pelo CDI. Por outro lado, o CDI pode ser usado em combinação com o EJB3 - por exemplo, adicionando suporte de escopo aos EJBs.

Reza Rahman, membro do grupo de especialistas e implementador de uma implementação de CDI chamada CanDI, freqüentemente sugeriu que os serviços associados ao modelo de componente EJB3 podem ser adaptados como um conjunto de anotações de CDI. Se isso acontecesse, todos os beans gerenciados em Java EE poderiam se tornar beans CDI. Isso não significa que o EJB3 desapareça ou se torne obsoleto, mas apenas que sua funcionalidade será exposta via CDI em vez de pelas próprias anotações do EJB, como @Stateless e @EJB.

Atualizar

David Blevins, da fama TomEE e OpenEJB, explica as diferenças e semelhanças entre CDI e EJB muito bem em seu blog: CDI, quando divulgar os EJBs

* Embora seja apenas um incremento no número da versão, os beans EJB3 eram, em sua maioria, um tipo de bean completamente diferente: um pojo simples que se torna um "bean gerenciado" aplicando uma única anotação simples, versus o modelo em EJB2 onde um peso pesado e O descritor de implantação XML excessivamente detalhado era necessário para cada bean, além do bean ser necessário para implementar várias interfaces de componentes extremamente pesadas e, em sua maioria, sem sentido.

** Os beans de sessão sem estado normalmente são agrupados, os beans de sessão com estado normalmente não (mas podem ser). Para ambos os tipos, o pool é, portanto, opcional e a especificação EJB não o exige de nenhuma forma.

Arjan Tijms
fonte
3
Estou um pouco confuso com suas declarações de que "os beans EJB3 não têm conceito de escopo" e que "o EJB3 não tem barramento de evento próprio". Como isso se encaixa com a afirmação de David Blevin de que "EJBs são beans CDI e, portanto, têm todos os benefícios do CDI"? Algo mudou a esse respeito entre quando você escreveu sua resposta e quando David escreveu sua entrada no blog?
Chris
5
É por causa do conceito talvez um pouco confuso que há , na verdade, não é realmente "CDI feijão", mas existem serviços aplicados a beans gerenciados. Para fins de discussão, as pessoas (e eu, portanto) se referem a eles como "beans CDI 'de qualquer maneira. Antes do CDI, os beans EJB não tinham escopo explícito. Como David explica, Stateful é implicitamente qualquer escopo (e, portanto, nenhum escopo em particular). Agora com o CDI disponível, os beans EJB podem aproveitar as vantagens dos escopos fornecidos pelo CDI. Sem a especificação do CDI, portanto, ao olhar apenas para a especificação EJB, não há escopos explícitos.
Arjan Tijms
1
Você pode explicar o que quer dizer com "existem serviços aplicados a beans gerenciados"? Isso significa que realmente não existe um bean CDI? São apenas alguns recursos extras que fornecem em um POJO - EJB - ou um JSF Managed Bean? Como poder usar a anotação Inject em um JSF Managed Bean?
Koray Tugay
3
@Chris para esclarecer melhor a partir de uma perspectiva de especificação de EJB, tomamos a decisão deliberada desde o início do CDI de exigir que as implementações de EJB suportem 100% do conjunto de recursos de CDI em EJBs. Cada aspecto do CDI funciona em EJBs, com exceção dos escopos que tivemos que limitar apenas aos beans com estado.
David Blevins
1
Observe que o JSF 2.2 agora fornece javax.faces.view.ViewScoped, uma extensão CDI que é essencialmente uma porta do escopo de visualização JSF para CDI. Com isso, o CDI é um substituto total para o JSF Managed Beans.
jdessey
-1

Albert Einstein: If you can't explain it simply, you don't understand it well enough

Ejbs e CDI são bastante simples de entender.

Ejbs:

  1. Sempre será anotado por qualificadores de escopo, por exemplo, @Stateless, @Stateful, @Request etc
  2. As instâncias de Ejbs são controladas pela estrutura Java EE e agrupadas. É dever da estrutura de EE fornecer as instâncias para o consumidor.

@Stateless

 public class CarMaker(){
    public void createCar(Specification specs){
        Car car = new Car(specs);
    }
}

O CarMaker é Anotado com escopo Ejbs específico, portanto, é Ejb

CDI:

  1. Não gerenciado inteiramente pela estrutura EE, as instâncias devem ser criadas por você.
  2. É sempre dependente. deixe-me explicar "Dependente" com um exemplo:

    class Specification { private String color; private String model; //- Getter and Setter }

A Specificationclasse é CDI, uma vez que não é anotada com escopos Ejb e também deve ser inicializada pelo seu código, não pela estrutura EE. Um ponto a ser observado aqui é que, uma vez que não anotamos a Specificationclasse, ela é, por padrão, Anotada por @Dependentanotação.

@Dependent  <- By default added 
class Specification { ... }

Further reading: Você precisa estudar mais entre a anotação de escopo Ejbs e a anotação de escopo CDI, que irá clarear ainda mais o conceito

HA S
fonte
Einstein também disse: "Tudo deve ser feito o mais simples possível, mas não mais simples", você pode (deve) substituir 'feito' por 'explicado' aqui.
Kukeltje