Introducción
Esta directriz se centra en el diseño de EJB. En la sección Directriz de producto de trabajo: EJB encontrará ayuda adicional sobre los EJB como,
por ejemplo, en la forma de identificarlos y modelarlos.
En las directrices que se indican a continuación encontrará ayuda específica sobre el diseño de tipos específicos EJB:
En la sección Concepto: visión general de J2EE: Enterprise JavaBeans se describen las interfaces
locales y remotas.
Las interfaces locales son más eficientes que las interfaces remotas. Se deberían proporcionar interfaces locales si
hay clientes específicos que son siempre locales respecto al EJB.
En las directrices para los tipos específicos de EJB encontrará ayuda más específica sobre este tema.
Paso de parámetros
El rendimiento puede verse afectado en gran medida según el número de llamadas remotas y la cantidad de datos que se
transfieren en cada llamada. Esto se puede resolver si se proporcionan llamadas específicas que devuelvan todos los
datos que requiere el cliente remoto. Por ejemplo, un bean de sesión, actuando como fachada de un conjunto de beans de
entidad relacionados, puede copiar datos de varios beans de entidad en objetos de valor serializable, y devolver estos
datos en una única llamada remota. Esto se describe en detalle en Core J2EE Patterns - Value Object Pattern ([ALU01]).
Hay que buscar un equilibrio entre esta estrategia y el mantener las interfaces lo más genéricas que sea posible así
como evitar el envío de demasiados datos innecesarios.
Demarcar transacciones significa iniciar transacciones, confirmar transacciones y tratar las transacciones que terminan
anormalmente. Un diseñador de EJB debe decidir cuándo implementar una demarcación de transacción gestionada por bean o
cuándo implementar una demarcación de transacción gestionada por contenedor. Hay que decidirlo en las ubicaciones de
los límites de la transacción en la secuencia de lógica empresarial que la aplicación realiza. Consulte las secciones
Tarea: diseño de guión de uso, modelado de transacciones y Gestión
de transacciones en Concepto: visión general de J2EE para obtener más información.
Es mejor utilizar transacciones gestionadas por contenedor siempre que sea posible. De esta forma mantendrá el código
simple y permitirá que los desarrolladores se centren en la lógica empresarial de la aplicación.
En general, las transacciones con una mayor granularidad dan lugar a un mejor rendimiento en general. Supongamos que se
realiza una secuencia de llamadas de método a un EJB (por ejemplo getX, getY y setZ). De forma predeterminada cada
método se ejecutará en una nueva transacción, dando lugar a un rendimiento más bajo. Para realizar estas llamadas
dentro de la misma transacción, habría que crear otro método, por ejemplo el método processXYZ de un EJB de sesión y
establecer los atributos de transacción de los métodos que se llaman en Required, de forma que utilizasen la
transacción existente (esto es, la transacción del método que llama en el bean de sesión).
Los conceptos relacionados con la seguridad básica de EJB se tratan en Concepto: visión general de la plataforma J2EE: seguridad.
Los requisitos de seguridad de EJB se establecen definiendo roles de seguridad y permisos de método.
Los roles de seguridad y los permisos de método se definen en el descriptor de despliegue del EJB. Es el
servidor (mediante la utilización de herramientas de administrador) quien debe correlacionar roles de seguridad con
usuarios o grupos de usuarios.
Un rol de seguridad define un conjunto de tipos similares de actividades que se agrupan bajo un único nombre. Un
permiso de método otorga a un rol de seguridad concreto el derecho de llamar al método. Por ejemplo, considere una
entidad EJB Employee, con los métodos setAddress, setSalary etc. A un rol de seguridad
manager se le podría otorgar un permiso de método para los métodos setAddress y setSalary, mientras que a un rol
de seguridad employee se le podría otorgar únicamente el permiso de método para el método
setAddress.
En algunas situaciones no es posible dar soporte a los requisitos de seguridad de una aplicación con permisos de
métodos declarados en el descriptor de despliegue. En este caso se utilizarían los métodos getCallerPrincipal e
isCallerInRole de la interfaz javax.ejb.EJBContext.
Desde J2EE 1.4 (con más exactitud, desde EJB 2.1) los beans de sesión sin estado y los beans controlados por mensajes
tienen la posibilidad de utilizar temporizadores para planificar procesos por lotes con el servicio de temporizador de
EJB.
El servicio de temporizador de EJB proporciona métodos que permiten devoluciones de llamada para planificar para
sucesos temporizados. El contenedor proporciona un servicio de notificación transaccional y fiable para sucesos
temporizados. Las notificaciones del temporizador se pueden planificar para que se produzcan en un momento específico
del tiempo, después de que haya transcurrido un intervalo de tiempo específico o en intervalos específicos que se
repiten periódicamente.
El contenedor EJB implementa el servicio de temporizador de forma que un EJB puede acceder a este servicio mediante la
interfaz EJBContext.
El servicio de temporizador de EJB es un servicio de notificación de temporizador estándar ("coarse-grained") diseñado
para utilizarlo en el modelado de procesos a nivel de aplicación y que no está pensado para modelar sucesos en tiempo
real.
Acceso directo frente a beans de entidad
La utilización de beans de entidad para los datos persistentes proporciona un mecanismo estándar y con muchas
características para acceder a los datos persistentes. La decisión de utilizar persistencia gestionada por bean o
persistencia gestionada por contenedor se puede ocultar a los clientes, proporcionando algo de flexibilidad al diseño.
Los EJB se pueden aprovechar de las características de transacciones, gestión de recursos, equilibrio de carga y otras
más que el entorno J2EE proporciona.
Sin embargo, podría haber situaciones en que se desee acceder directamente a la base de datos evitando el utilizar
beans de entidad. Por ejemplo, si siempre se accede a los datos en modalidad de sólo lectura por un único cliente, el
acceso directo a la base de datos sería más eficiente.
Si se accede directamente a la base de datos (por ejemplo, desde un bean de sesión sin estado), se debe encapsular todo
el acceso a la base de datos dentro de una clase DAO (Data Access Object). Tan sólo se trata de una clase Java que
oculta y encapsula el mecanismo de almacenamiento que subyace detrás ella y que aísla de los cambios en la interfaz al
origen de datos, si es que cambia. Consulte Core J2EE Patterns - Data Access Object Pattern ([ALU01]) para obtener más información.
Prácticamente todos los contenedores EJB proporcionan soporte a la agrupación de conexiones, compartiendo un conjunto
de conexiones ya creadas entre los clientes. Estas conexiones se asignan a los EJB siempre que es necesario. Los EJB
sacan partido al hecho de obtener una conexión sin el gasto que supone crearla e inicializarla. Cuando la conexión se
devuelve a la agrupación, se recicla. El tamaño de la agrupación debería tener disponibles las suficientes conexiones
listas para reciclar las utilizadas.
Con beans de entidad con persistencia gestionada por contenedor, el contenedor gestiona la conexión con la base de
datos y accede a la agrupación de conexiones de base de datos.
Con beans de entidad gestionados por persistencia (o para los EJB de sesión o controlados por mensajes que acceden a
una base de datos), corresponde al desarrollador codificar la rutina de conexión. Se deberían seguir estas normas:
-
Aislar el código de acceso a la base de datos en una clase DAO.
-
No codificar por programa el URL real de la base de datos; en lugar de ello, es mejor utilizar un nombre lógico que
se pueda recuperar con una búsqueda JNDI (Java Naming and Directory Interface). De esta forma es posible reutilizar
el EJB en varias aplicaciones, posiblemente con distintos nombres de base de datos.
-
En general, es mejor utilizar agrupaciones de conexiones, y sólo retener la conexión mientras se necesita. Por
ejemplo, un bean de entidad se podría conectar, actualizar una fila en la tabla y a continuación desconectarse. De
esta forma se permite que muchos EJB compartan la misma conexión. La especificación JDBC da soporte a la agrupación
de conexiones.
|