En comparación con EJB 2.1, EJB 3.1 simplifica el proceso de creación de aplicaciones Enterprise Java™ Bean.
EJB 2.x y la complejidad de la arquitectura J2EE 1.4
Capa empresarial En la arquitectura
J2EE 1.4, los beans de sesión se utilizan para recalcular componentes de lógica empresarial, proporcionándoles servicios transaccionales, distribuidos, remotos y de seguridad. Suelen implementar un patrón de fechada para reducir el tráfico de red entre el cliente y el proveedor de servicios.
Es posible acceder a los beans de sesión a través de clientes locales (lo que significa clientes que residen dentro de la misma JVM) o clientes remotos.
Los beans controlados por mensajes se utilizan para integrar proveedores JMS externos (como, por ejemplo, MQSeries) con el fin de habilitar los servicios de gestión de mensajes asíncronos.
Los beans de sesión y los beans gestionados por mensajes constituyen conjuntamente la capa de lógica empresarial. Se denominan capas porque otro paradigma fundamental adoptado en el diseño de esta arquitectura empresarial es la distribución por capas, lo que habilita características básicas como, por ejemplo, separación de tareas y habilidades, la agrupación en clúster y la reutilización de componentes.
Capa de persistencia La otra capa fundamental es la capa de persistencia, que es el conjunto de servicios y componentes que permiten que la aplicación de datos sea persistente en una base de datos relacional. La capa de persistencia puede implementarse de estas maneras:
- Beans de entidad (beans gestionados por contenedor y beans gestionados por beans)
- Objetos de acceso de datos JDBC™ (DAO)
- Infraestructuras de correlaciones relacionales de objeto (ORM)
Problemas con la especificación EJB 2.x
- En la especificación EJB 2.x, la interfaz de componente debe ampliar una interfaz del paquete de infraestructura EJB, y la clase de implementación de lógica empresarial debe implementar una interfaz del paquete de infraestructura EJB. Estos requisitos crean un acoplamiento estrecho entre el código escrito por el desarrollador y las clases de interfaz del paquete de infraestructura EJB. También requiere la implementación de varios métodos de devolución de llamadas innecesarios (ejbCreate, ejbPassivate, ejbActivate) no directamente relacionados con el objetivo principal del diseño del EJB y el manejo de excepciones innecesarias.
- Los descriptores de despliegue EJB son demasiado verbosos, complejos y propensos a errores.
- Es difícil comprobar los beans EJB dado que la aplicación
requiere un contenedor J2EE para proporcionar todos los servicios
necesarios con el fin de ejecutar correctamente el componente EJB.
- La dependencia en JNDI cada vez que se tiene que acceder a un recurso (como un origen de datos o una referencia inicial de EJB) es una operación repetitiva y tediosa en el desarrollo de J2EE.
- El desarrollo y la gestión del modelo de persistencia gestionado por contenedor son complejos.
Modelo simplificado en EJB 3.1
La arquitectura global de Java EE y EJB 3.1 refleja la simplificación del modelo de EJB 3.1:

El concepto subyacente de la especificación EJB 3.1 se centra en un modelo de programación de objetos Java (POJO) simple y antiguo que utiliza anotaciones Java para capturar información que los descriptores de despliegue utilizan para contenerla. Los descriptores de despliegue ahora son opcionales en la mayoría de los casos. La utilización generosa de valores predeterminados también significa que necesita escribir y
mantener menos código de soporte. De este modo se simplifica enormemente la experiencia de programación a la hora de crear y utilizar componentes de
EJB 3.1. Las características principales de este modelo simplificado son
- Los EJB ahora son objetos POJO (Plain Old Java Object) que exponen interfaces de empresa normales (POJI) y no hay ningún requisito para interfaces de inicio.
- La utilización de anotaciones de metadatos: una infraestructura ampliable, gestionada por metadatos, orientada a atributos, que se emplea para generar código Java o descriptores de despliegue XML.
- La eliminación del requisito de interfaces y descriptores de despliegue (la información de descriptor de despliegue se puede sustituir por anotaciones) específicos.
- El recurso interceptor para invocar métodos de usuario en la invocación de métodos empresariales o eventos de ciclo de vida.
- Los valores predeterminados se utilizan siempre que sea posible (enfoque "configuración por excepción").
- La reducción en los requisitos para la utilización de la excepción marcada.
- Un nuevo modelo de persistencia completo (basado en el estándar JPA), que reemplaza beans de entidad EJB 2.x.
Tabla 1. Comparación de pasos para crear beans en EJB 2.1 y en EJB 3.1 . EJB 2.x utiliza descriptores de despliegue y EJB 3.1 utiliza anotaciones. Pasos para definir un bean de sesión sin estado en EJB 2.x |
Pasos para definir un bean de sesión sin estado en EJB 3.1 |
Para crear un bean de sesión sin estado
según la especificación EJB 2.x, defina los componentes siguientes:
- Interfaz de componente EJB: utilizada por un cliente EJB para obtener acceso a las posibilidades del bean. Aquí se definen los métodos empresariales.
La interfaz de componente se conoce como el objeto EJB. Hay dos tipos de interfaces de componente:
- Interfaz de componente remota (EJBObject): utilizada por un cliente remoto para acceder al EJB a través del protocolo RMI-IIOP.
- Interfaz de componente local (EJBLocalObject): utilizada por un cliente local (que se ejecuta en la misma JVM) para acceder al EJB.
- Interfaz inicial EJB: utilizada por un cliente EJB para obtener acceso al bean. Contiene los métodos de ciclo de vida del bean: crear, buscar o eliminar.
La interfaz inicial se conoce como el inicio EJB. El objeto EJBHome es un objeto que implementa la interfaz inicial y, al igual que EJBObject, se genera a partir de las herramientas de contenedor durante el despliegue e incluye código específico del contenedor. En el momento del arranque, el contenedor EJB instancia los objetos EJBHome de los enterprise beans desplegados y lo registra en el servicio de denominación. Un cliente EJB accede a los objetos
EJBHome mediante JNDI (Java Naming and Directory
Interface). Hay dos tipos de interfaces iniciales:
- Interfaz inicial remota (EJBHome): utilizada por un cliente remoto para acceder al EJB a través del protocolo RMI-IIOP.
- Interfaz inicial local (EJBLocalHome): utilizada por un cliente local (que se ejecuta en la misma JVM) para acceder al EJB.
- Clase de bean EJB: Contiene toda la lógica empresarial de los beans actuales.
Es la clase que proporciona la implementación de lógica empresarial. Los métodos en esta clase de bean se asocian con los métodos en las interfaces inicial y de componente.
|
Para declarar un bean de sesión sin estado según la especificación EJB 3.1, defina simplemente un POJO:
@Stateless
public class MySessionBean implements MyBusinessInterface {
// métodos empresariales según MyBusinessInterface
.....
}
- Para exponer el mismo bean en la interfaz remota, utilice la anotación @Remote:
@Remote(MyRemoteBusinessInterface.class)
@Stateless
public class MyBean implements MyRemoteBusinessInterface {
// métodos ejb
.....
}
|
Comparación de la clase de EJB 2.1 más el archivo de descriptor de despliegue con la clase equivalente de EJB 3.1
Los ejemplos de la Tabla 1 son funcionalmente equivalentes:
Tabla 2. Comparación de EJB 2.1 y EJB 3.1 . EJB 2.1 utiliza descriptores de despliegue y EJB 3.1 utiliza anotaciones. EJB 2.1 |
EJB 3.1 |
Clase Java
public class AccountBean
implements javax.ejb.SessionBean {
SessionContext ctx;
DataSource accountDB;
public void setSessionContext(SessionContext ctx) {
this.ctx = ctx;
}
public void ejbCreate() {
accountDB = (DataSource)ctx.lookup(
"jdbc/accountDB");
}
public void ejbActivate() { }
public void ejbPassivate() { }
public void ejbRemove() { }
public void setAccountDeposit(int empId,
double deposit) {
...
Connection conn = accountDB.getConnection();
...
}
...
}
|
Clase Java
@Stateless
public class AccountBean implements Account
{
@Resource private DataSource accountDB;
public void setAccountDeposit(int customerId,
double deposit) {
...
Connection conn = accountDB.getConnection();
...
}
...
}
|
Descriptor de despliegue
<session>
<ejb-name>AccountBean</ejb-name>
<local-home>AccountHome</local-home>
<local>Account</local>
<ejb-class>com.example.AccountBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<resource-ref>
<res-ref-name>jdbc/accountDB</res-ref-name>
<res-ref-type>javax.sql.DataSource</res-ref-type>
<res-auth>Container</res-auth> </resource-ref>
</session>
...
<assembly-descriptor>...</assembly-descriptor>
|
|