¿Qué es un EJB y qué hace?

151

He estado tratando de aprender qué EJBson los beans, qué significa que sus instancias se administran en un grupo, bla, bla. Realmente no puedo tener un buen agarre de ellos.

¿Me puede explicar cuáles son realmente (prácticamente para un programador de Java)? ¿Qué hacen? ¿Cuáles son sus propósitos? ¿Por qué realmente usarlos? (¿Por qué no simplemente seguir POJO?) ¿ Quizás una aplicación de ejemplo?

Consulte solo la información actualizada, es decir EJB 3.1. La información fechada sobre EJB puede ser engañosa.

Para principiantes de aprendizaje de EJB, tenga en cuenta:

Los EJB se basan en objetos distribuidos , esto se refiere a piezas de software que se ejecutan en varias máquinas (virtuales o físicas) vinculadas por una red .

Jacktrades
fuente

Respuestas:

161

¿Por qué realmente usarlos? (¿Por qué no quedarse con POJO?)

SI necesita un componente que acceda a la base de datos, o acceda a otros recursos de conectividad / directorio, o sea accedido desde múltiples clientes, o esté destinado como un servicio SOA, los EJB de hoy en día suelen ser "más grandes, más fuertes, más rápidos (o al menos más escalables) y más simple "que POJOs. Son más valiosos para atender a un gran número de usuarios a través de la red corporativa o web y algo menos valiosos para pequeñas aplicaciones dentro de un departamento.

  1. Reutilizando / compartiendo lógica en múltiples aplicaciones / clientes con acoplamiento flexible
    Los EJB se pueden empaquetar en sus propios frascos, desplegar e invocar desde muchos lugares. Son componentes comunes. Es cierto que los POJO pueden diseñarse (¡con cuidado!) Como bibliotecas y empaquetarse como frascos. Pero los EJB son compatibles con el acceso a la red local y remota, incluso a través de la interfaz local de Java, RMI transparente, mensaje asíncrono JMS y servicio web SOAP / REST, ahorrando de dependencias jar de cortar y pegar con implementaciones múltiples (¿inconsistentes?).
    Son muy útiles para crear servicios SOA. Cuando se usan para acceso local, son POJO (con servicios de contenedor gratuitos agregados). El acto de diseñar una capa EJB separada promueve un cuidado adicional para maximizar la encapsulación, el acoplamiento flojo y la cohesión, y promueve una interfaz limpia (Fachada), protegiendo a las personas que llaman de modelos complejos de procesamiento y datos.

  2. Escalabilidad y confiabilidad Si aplica una cantidad masiva de solicitudes de varios mensajes / procesos / subprocesos de llamada, primero se distribuyen entre las instancias EJB disponibles en el grupo y luego se ponen en cola. Esto significa que si el número de solicitudes entrantes por segundo es mayor de lo que el servidor puede manejar, nos degradamos con gracia: siempre hay algunas solicitudes que se procesan de manera eficiente y el exceso de solicitudes se hace esperar. No llegamos al "colapso" del servidor, donde TODAS las solicitudes experimentan un tiempo de respuesta terrible simultáneamente, además el servidor intenta acceder a más recursos de los que el hardware y el sistema operativo pueden manejar y, por lo tanto, se bloquea. Los EJB se pueden implementar en un nivel separado que se puede agrupar: esto brinda confiabilidad a través de la conmutación por error de un servidor a otro, además de que se puede agregar hardware para escalar linealmente.

  3. Gestión de concurrencia. El contenedor asegura que múltiples clientes tengan acceso automático a las instancias EJB de forma segura (en serie). El contenedor gestiona el grupo EJB, el grupo de subprocesos, la cola de invocación y realiza automáticamente el bloqueo de escritura a nivel de método (predeterminado) o el bloqueo de lectura (a través de @Lock (READ)). Esto protege los datos de la corrupción a través de conflictos concurrentes de escritura y escritura, y ayuda a que los datos se lean de manera consistente al evitar conflictos de lectura y escritura.
    Esto es principalmente útil para los beans de sesión @Singleton, donde el bean está manipulando y compartiendo un estado común entre los clientes que llaman. Esto se puede anular fácilmente para configurar manualmente o controlar mediante programación escenarios avanzados para la ejecución concurrente de código y el acceso a datos.

  4. Manejo automatizado de transacciones.
    No haga nada y todos sus métodos EJB se ejecutan en una transacción JTA. Si accede a una base de datos utilizando JPA o JDBC, se registra automáticamente en la transacción. Lo mismo para las invocaciones JMS y JCA. Especifique @TransactionAttribute (someTransactionMode) antes de un método para especificar si / cómo ese método en particular participa en la transacción JTA, anulando el modo predeterminado: "Obligatorio".

  5. Acceso muy simple a recursos / dependencias por inyección.
    El contenedor buscará recursos y establecerá referencias de recursos como campos de instancia en el EJB: como conexiones JDBC almacenadas JNDI, conexiones / temas / colas JMS, otros EJB, transacciones JTA, contextos de persistencia del administrador de entidades JPA, unidades de persistencia de fábrica del administrador de entidades JPA y Recursos del adaptador JCA. por ejemplo, para configurar una referencia a otro EJB y una Transacción JTA y un Gerente de entidad JPA y una fábrica y cola de conexiones JMS:

    @Stateless
    public class MyAccountsBean {
    
        @EJB SomeOtherBeanClass someOtherBean;
        @Resource UserTransaction jtaTx;
        @PersistenceContext(unitName="AccountsPU") EntityManager em;
        @Resource QueueConnectionFactory accountsJMSfactory;
        @Resource Queue accountPaymentDestinationQueue;
    
        public List<Account> processAccounts(DepartmentId id) {
            // Use all of above instance variables with no additional setup.
            // They automatically partake in a (server coordinated) JTA transaction
        }
    }
    

    Un Servlet puede llamar a este bean localmente, simplemente declarando una variable de instancia:

    @EJB MyAccountsBean accountsBean;    
    

    y luego simplemente llamando a sus métodos según lo deseado.

  6. Interacción inteligente con JPA. De forma predeterminada, el EntityManager inyectado como anteriormente usa un contexto de persistencia con ámbito de transacción. Esto es perfecto para beans de sesión sin estado. Cuando se llama a un método EJB (sin estado), se crea un nuevo contexto de persistencia dentro de la nueva transacción, todas las instancias de objeto de entidad recuperadas / escritas en la base de datos son visibles solo dentro de esa llamada al método y están aisladas de otros métodos. Pero si el método llama a otros EJB sin estado, el contenedor se propaga y comparte la misma PC con ellos, por lo que las mismas entidades se comparten automáticamente de manera consistente a través de la PC en la misma transacción.
    Si se declara un bean de sesión @Stateful, se logra una afinidad inteligente igual con JPA al declarar el entityManager como un alcance extendido: @PersistentContent (unitName = "AccountsPU, type = EXTENDED). Esto existe durante la vida de la sesión de bean, a través de múltiples llamadas de frijol y transacciones, almacenando en caché copias en memoria de entidades DB previamente recuperadas / escritas para que no necesiten ser recuperadas nuevamente.

  7. Gestión del ciclo de vida. El ciclo de vida de los EJB se gestiona en contenedores. Según sea necesario, crea instancias EJB, borra e inicializa el estado de bean de sesión con estado, pasiva y activa, y llama a los métodos de devolución de llamadas del ciclo de vida, por lo que el código EJB puede participar en las operaciones del ciclo de vida para adquirir y liberar recursos, o realizar otro comportamiento de inicialización y apagado. También captura todas las excepciones, las registra, revierte las transacciones según sea necesario y lanza nuevas excepciones EJB o @ApplicationExceptions según sea necesario.

  8. Gestion de seguridad. El control de acceso basado en roles a los EJB se puede configurar mediante una anotación simple o una configuración XML. El servidor pasa automáticamente los detalles del usuario autenticado junto con cada llamada como contexto de seguridad (el principal y el rol de la llamada). Asegura que todas las reglas RBAC se apliquen automáticamente para que los métodos no puedan ser invocados ilegalmente por el rol incorrecto. Permite a los EJB acceder fácilmente a los detalles del usuario / rol para una verificación programática adicional. Permite conectar un procesamiento de seguridad adicional (o incluso herramientas IAM) al contenedor de forma estándar.

  9. Estandarización y Portabilidad. Las implementaciones de EJB cumplen con los estándares de Java EE y las convenciones de codificación, promoviendo la calidad y la facilidad de comprensión y mantenimiento. También promueve la portabilidad del código a los nuevos servidores de aplicaciones de proveedores, al garantizar que todos admitan las mismas características y comportamientos estándar, y al disuadir a los desarrolladores de adoptar accidentalmente
    características de proveedores no portátiles patentados .

  10. El verdadero pateador: simplicidad. Todo lo anterior se puede hacer con un código muy simplificado, ya sea utilizando la configuración predeterminada para EJB en Java EE 6 o agregando algunas anotaciones. La codificación de características de fuerza industrial / empresarial en sus propios POJO sería mucho más voluminosa, compleja y propensa a errores. Una vez que comience a codificar con EJB, son bastante fáciles de desarrollar y ofrecen un gran conjunto de beneficios de "viaje gratis".

En la especificación original de EJB de hace 10 años, los EJB eran una molestia importante para la productividad. Estaban hinchados, necesitaban mucho código y artefactos de configuración y proporcionaban aproximadamente 2/3 de los beneficios anteriores. La mayoría de los proyectos web en realidad no los usaban. Pero esto ha cambiado significativamente con 10 años de ajustes, revisiones, mejoras funcionales y desarrollo de líneas de flujo. En Java EE 6 proporcionan la máxima resistencia industrial y la simplicidad de uso.

¿¿Que es no gustar?? :-) :-)

Glen Best
fuente
67

Un EJB es un componente de Java, que contiene lógica de negocios, que implementa en un contenedor y que se beneficia de los servicios técnicos proporcionados por el contenedor, generalmente de forma declarativa, gracias a las anotaciones:

  • gestión de transacciones: una transacción puede iniciarse automáticamente antes de que se invoque un método de EJB, y confirmarse o revertirse una vez que este método regrese. Este contexto transaccional se propaga a llamadas a otros EJB.
  • gestión de seguridad: se puede verificar que la persona que llama tenga los roles necesarios para ejecutar el método.
  • inyección de dependencia: se pueden inyectar otros EJB o recursos como un administrador de entidades JPA, un origen de datos JDBC, etc. en el EJB.
  • concurrencia: el contenedor se asegura de que solo un hilo a la vez invoque un método de su instancia EJB.
  • distribución: algunos EJB se pueden llamar de forma remota, desde otra JVM.
  • conmutación por error y equilibrio de carga: los clientes remotos de sus EJB pueden redirigir automáticamente su llamada a otro servidor si es necesario.
  • gestión de recursos: los beans con estado pueden pasivarse automáticamente al disco para limitar el consumo de memoria de su servidor.
  • ... Probablemente he olvidado algunos puntos.
JB Nizet
fuente
Cuando se refiere a la transacción, ¿se refiere a la persistencia?
Jacktrades
66
Sí, pero no solo Los contenedores EJB proporcionan un administrador de transacciones JTA distribuido, que admite múltiples recursos en una sola transacción. Podría, por ejemplo, actualizar algunos datos en una base de datos y enviar algunos mensajes JMS en una sola transacción. Si algo fallara, todo se revertiría: las actualizaciones de la base de datos y los mensajes enviados.
JB Nizet
@JBNizet discúlpeme por comentar sobre un hilo antiguo, pero NO los marcos EJB como Spring están proporcionando estos servicios que usted mencionó. no entiendo la diferencia
MoienGK
Los principios básicos son los mismos. Spring tomó ideas de EJBs y viceversa. Pero la API, la implementación, la forma de implementación y algunas características son diferentes.
JB Nizet
@JB Nizet En el patrón MVC, ¿dónde colocarías EJBs en general? Diría que pertenecen a la capa Modelo, aunque conozco a muchas personas que dicen que son controladores. Si EJB contiene lógica de negocios (usted dijo que sí), entonces son capa de modelo por definición.
user107986
22

Espero que esto de Oracle doc ayude a alguien como yo a comprender el tema de EJB de una manera simple.

¿Qué es un bean empresarial? Escrito en el lenguaje de programación Java, un Enterprise Bean es un componente del lado del servidor que encapsula la lógica de negocios de una aplicación. La lógica de negocios es el código que cumple el propósito de la aplicación. En una aplicación de control de inventario, por ejemplo, los beans empresariales pueden implementar la lógica de negocios en métodos llamados checkInventoryLevel y orderProduct. Al invocar estos métodos, los clientes pueden acceder a los servicios de inventario proporcionados por la aplicación.

Beneficios de los Enterprise Beans Por varias razones, los Enterprise Beans simplifican el desarrollo de grandes aplicaciones distribuidas. Primero, debido a que el contenedor EJB proporciona servicios de nivel de sistema a beans empresariales, el desarrollador de beans puede concentrarse en resolver problemas comerciales. El contenedor EJB, en lugar del desarrollador de beans, es responsable de los servicios a nivel del sistema, como la gestión de transacciones y la autorización de seguridad.

Segundo, debido a que los beans en lugar de los clientes contienen la lógica de negocios de la aplicación, el desarrollador del cliente puede enfocarse en la presentación del cliente. El desarrollador del cliente no tiene que codificar las rutinas que implementan las reglas de negocios o las bases de datos de acceso. Como resultado, los clientes son más delgados, un beneficio que es particularmente importante para los clientes que se ejecutan en dispositivos pequeños.

Tercero, debido a que los beans empresariales son componentes portátiles, el ensamblador de aplicaciones puede construir nuevas aplicaciones a partir de beans existentes. Estas aplicaciones pueden ejecutarse en cualquier servidor Java EE compatible siempre que utilicen las API estándar.

Cuándo usar Enterprise Beans Debe considerar usar Enterprise Beans si su aplicación tiene alguno de los siguientes requisitos:

La aplicación debe ser escalable. Para dar cabida a un número creciente de usuarios, es posible que deba distribuir los componentes de una aplicación en varias máquinas. Los beans empresariales de una aplicación no solo pueden ejecutarse en diferentes máquinas, sino que también su ubicación será transparente para los clientes.

Las transacciones deben garantizar la integridad de los datos. Los beans Enterprise admiten transacciones, los mecanismos que gestionan el acceso concurrente de objetos compartidos.

La aplicación tendrá una variedad de clientes. Con solo unas pocas líneas de código, los clientes remotos pueden localizar fácilmente beans empresariales. Estos clientes pueden ser delgados, diversos y numerosos.

Tesfa Zelalem
fuente
3

La pregunta que más me interesa es cómo y dónde puedo usarlos. Para entender esto, primero necesitamos ver qué tipos de EJB existen. Hay 2 grandes categorías:

  1. Frijoles de sesión
  2. Frijoles impulsados ​​por mensajes

Consideremos los beans de sesión. Son de 3 tipos:

  1. Con estado : estos componentes mantienen el estado y son específicos para un cliente en múltiples solicitudes. Véalo como una sesión. El uso inmediato que se les puede dar es comprar carros u otro tipo de sesiones (sesión de inicio de sesión, etc.)
  2. Sin estado : son componentes autónomos que no persisten en la información entre solicitudes, pero son exclusivos del usuario. Uso inmediato que viene a la mente: clases de servicio en la capa de servicio . Imaginar OrderService. Otro gran uso de estos es exponer los servicios web. De nuevo, esto estará en la capa de Servicio o totalmente separado.
  3. Singleton : estos son los beans que existen por aplicación y se crean una vez y se pueden reutilizar / acceder varias veces. Inmediatamente me Configurationviene a la mente el componente, donde puede almacenar configuraciones de nivel de aplicación y acceder a ellas cuando las necesite desde cualquier lugar.

Ahora, el resto de las capacidades o características se pueden usar en todas las capas en cualquiera de estas situaciones:

  • Seguridad : puede verificar los permisos con una anotación en el método que se llama. Esto puede suceder en la capa de servicio, así como en el controlador, si así lo desea.
  • Gestión de transacciones : este es el candidato obvio en la capa de servicio o la capa de persistencia
  • Inyección de dependencia : nuevamente se usará en todas partes

Un gran uso en los tiempos modernos son los llamados microservicios y arquitecturas orientadas a servicios. Puede empaquetar algunos componentes de lógica de negocios como EJB y distribuirlos en toda la organización, para ser utilizados por varios clientes (por cliente aquí me refiero a otras aplicaciones de fondo).

Y así. Ahora, el gran inconveniente es que te vuelves muy dependiente del contenedor EJB y, aunque puedes cambiar entre 2 implementaciones de referencia, no podrás cambiar a algo más ligero: Tomcat, por ejemplo. ¿Pero por qué querrías sacrificar todos los beneficios?

ACV
fuente