¿Cómo se comparan CDI y EJB? ¿interactuar?

Me está costando entender cómo interactúan los dos y dónde se encuentra el límite entre ellos. ¿Se superponen? ¿Hay redundancias entre ellos?

Sé que hay anotaciones asociadas con ambos, pero no he podido encontrar una lista completa para ambos con breves descripciones. No estoy seguro de si esto ayudaría a aclarar cómo difieren o dónde se superponen.

Realmente solo confundido. Yo (creo que) entiendo EJB razonablemente bien, creo que me está costando entender exactamente lo que CDI trae a la mesa y cómo suplanta o mejora lo que EJB ya ofrece.

CDI: se trata de dependency injection. Significa que puede inyectar la implementación de la interfaz en cualquier lugar. Este objeto puede ser cualquier cosa, no puede estar relacionado con EJB. Aquí hay un ejemplo de cómo inyectar generador aleatorio usando CDI. No hay nada sobre EJB. Vas a utilizar CDI cuando quieras inyectar servicios que no sean EJB, diferentes implementaciones o algoritmos (para que no necesites EJB en absoluto).
EJB lo entiendes, y probablemente estés confundido por la anotación @EJB, te permite inyectar implementación en tu servicio o lo que sea. La idea principal es que la clase, donde se inyecta, debe ser administrada por el contenedor EJB. Parece que CDI no comprende qué es EJB, así que en el servidor compatible con Java EE 6, en su servlet puede escribir ambos

@EJB EJBService ejbService; 

y

 @Inject EJBService ejbService; 

eso es lo que puede confundirte, pero eso es probablemente lo único que es el puente entre EJB y CDI.

Cuando hablamos de CDI, puede inyectar otros objetos en las clases administradas por CDI (solo deberían ser creados por marcos compatibles con CDI).

Qué más ofrece CDI … Por ejemplo, usa Struts 2 como framework MVC (solo ejemplo), y está limitado aquí, incluso usando EJB 3.1 – no puede usar la anotación @EJB en la acción Struts, no es administrado por envase. Pero cuando agrega el plugin Struts2-CDI, puede escribir allí @Inject annotation para la misma cosa (por lo que no se necesita más búsqueda JNDI). De esta forma mejora la potencia de EJB. Pero como mencioné antes, lo que inyectas con CDI, no importa si está relacionado con EJB o no, y ese es su poder

PD. enlace actualizado al ejemplo

De hecho, actualmente es un poco confuso ya que ahora hay modelos de componentes múltiples en Java EE. Son frijoles gestionados CDI , EJB3 y JSF .

CDI es el nuevo niño en el bloque. Los beans CDI presentan dependency injection , scoping y un event bus . Los frijoles CDI son los más flexibles con respecto a la inyección y el scope. El bus de eventos es muy liviano y muy adecuado incluso para las aplicaciones web más sencillas. Además de esto, CDI también expone una característica muy avanzada llamada portable extensions , que es un tipo de mecanismo de complemento para que los proveedores proporcionen funcionalidad adicional a Java EE que puede estar disponible en todas las implementaciones (Glassfish, JBoss AS, Websphere, etc.)

Los beans EJB3 fueron retroadaptados desde el antiguo modelo de componente EJB2 heredado * y fueron los primeros beans en Java EE en ser administrados por medio de una anotación. Los beans EJB3 presentan dependency injection , declarative transactions , declarative security , pooling , concurrency control , asynchronous execution y remoting .

La dependency injection en beans EJB3 no es tan flexible como en los beans CDI y los beans EJB3 no tienen ningún concepto de scope. Sin embargo, los beans EJB3 son transaccionales y se agrupan por defecto ** , dos cosas muy utilizables que CDI ha elegido dejar en el dominio de EJB3. Los otros artículos mencionados tampoco están disponibles en CDI. EJB3 no tiene bus de eventos propios, pero sí tiene un tipo especial de bean para escuchar mensajes; el mensaje conducido frijol Esto se puede usar para recibir mensajes de Java Messaging System o de cualquier otro sistema que tenga un adaptador de recursos JCA. El uso de mensajes completos para eventos simples es mucho más pesado que el bus de eventos CDI y EJB3 solo define un oyente, no una API de productor.

Los beans administrados JSF han existido en Java EE desde que se incluyó JSF. Ellos también cuentan con dependency injection y scoping . JSF Managed Beans introdujo el concepto de scope declarativo. Originalmente, los ámbitos eran bastante limitados y en la misma versión de Java EE donde los beans EJB3 ya podían declararse mediante anotaciones, JSF Managed Beans aún tenía que declararse en XML. La versión actual de JSF Managed Beans también se declara finalmente a través de una anotación y los ámbitos se amplían con un scope de vista y la capacidad de crear ámbitos personalizados. El scope de la vista, que recuerda los datos entre las solicitudes a la misma página, es una característica única de JSF Managed Beans.

Además del scope de la vista, todavía falta muy poco para JSF Managed Beans en Java EE 6. El scope de vista faltante en CDI es desafortunado, ya que de lo contrario CDI hubiera sido un super conjunto perfecto de lo que ofrece JSF Managed Beans. Actualización : en Java EE 7 / JSF 2.2 se ha agregado un CDI compatible @ViewScoped , lo que hace que el CDI sea el super set perfecto. Actualización 2 : en JSF2.3, los beans gestionados de JSF han quedado en desuso en favor de los beans gestionados de CDI.

Con EJB3 y CDI la situación no es tan clara. El modelo de componentes EJB3 y la API ofrecen una gran cantidad de servicios que CDI no ofrece, por lo que normalmente EJB3 no puede ser reemplazado por CDI. Por otro lado, CDI se puede usar en combinación con EJB3, por ejemplo, agregando soporte de scope a los EJB.

Reza Rahman, miembro del grupo de expertos e implementador de una implementación de CDI llamada CanDI, ha insinuado con frecuencia que los servicios asociados con el modelo de componentes EJB3 se pueden actualizar como un conjunto de anotaciones CDI. Si eso sucediera, todos los beans administrados en Java EE podrían convertirse en beans CDI. Esto no significa que EJB3 desaparece o se vuelve obsoleto, sino que su funcionalidad quedará expuesta a través de CDI en lugar de a través de las propias anotaciones de EJB como @Stateless y @EJB.

Actualizar

David Blevins de TomEE y la fama de OpenEJB explican muy bien las diferencias y similitudes entre CDI y EJB en su blog: CDI, cuándo dividir los EJB

* Aunque es solo un incremento en el número de versión, los beans EJB3 fueron en su mayoría un tipo de bean completamente diferente: un simple pojo que se convierte en un “bean gestionado” al aplicar una simple anotación simple, frente al modelo en EJB2 donde un peso pesado y Se requirió un descriptor de despliegue XML demasiado detallado para todos y cada uno de los beans, además de que el bean debe implementar varias interfaces de componentes extremadamente pesados ​​y en su mayor parte sin sentido.

** Los beans de sesión sin estado suelen agruparse, los beans de sesión con estado normalmente no (pero pueden serlo). Para ambos tipos, la agrupación es opcional y la especificación EJB no lo ordena de ninguna manera.

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

Ejbs y CDI son bastante simples de entender.

Ejbs:

  1. Siempre será anotado por los calificadores del scope, por ejemplo, @Stateless, @Stateful, @Request, etc.
  2. Las instancias de Ejbs están controladas por el marco Java EE y agrupadas. Es el deber del marco EE proporcionar las instancias para el consumidor.

@Stateless

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

El CarMaker está anotado con un scope Ejbs específico, por lo tanto, es Ejb

CDI:

  1. No administrado completamente por el marco EE, las instancias deben ser creadas por usted mismo.
  2. Siempre es dependiente déjame explicar “Dependiente” con un ejemplo:

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

La clase de Specification es CDI, ya que no está anotada con ámbitos Ejb y también tiene que inicializarse con su código y no con EE framework. Un punto que debe tenerse en cuenta aquí es que, dado que no anotamos la clase de Specification , está anotada de forma predeterminada por la anotación @Dependent .

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

Further reading: debe estudiar más entre la anotación de scope de Ejbs y la anotación de scope CDI, que borrará aún más el concepto.