entre ejemplo diferencia java singleton ejb-3.0 ejb stateless

java - ejemplo - ejb singleton load on startup



Frijoles de sesión sin estado frente a frijoles de sesión Singleton (8)

El tutorial de Java EE 6 dice:

Para mejorar el rendimiento, puede elegir un bean de sesión sin estado si tiene alguno de estos rasgos:

  • El estado del bean no tiene datos para un cliente específico.
  • En una invocación de un solo método, el bean realiza una tarea genérica para todos los clientes. Por ejemplo, puede usar un bean de sesión sin estado para enviar un correo electrónico que confirme un pedido en línea.
  • El bean implementa un servicio web.

Los beans de sesión Singleton son apropiados en las siguientes circunstancias:

  • El estado debe ser compartido a través de la aplicación.
  • Un único enterprise bean debe ser accedido por múltiples hilos al mismo tiempo.
  • La aplicación necesita un bean empresarial para realizar tareas en el inicio y cierre de la aplicación.
  • El bean implementa un servicio web.

Pero qué usar si:

  • Ningún estado tiene que ser compartido a través de la aplicación.
  • Se puede acceder a un solo enterprise bean por varios hilos simultáneamente
  • No es necesario realizar tareas en el inicio o en el disparo.

Digamos por ejemplo que tengo un servicio de inicio de sesión con la siguiente interfaz:

public interface LoginService { boolean authenticate(String user, String password); }

¿Debe ser anotado con @Singleton o @Stateless? ¿Cuáles son los beneficios de lo uno y lo otro? ¿Qué pasa si LoginService necesita inyectar un EntityManager (que se usaría simultáneamente)?

Adición: Estoy pensando en la contraparte de Java EE de los beans de servicio Spring, que son singletons sin estado. Si comprendo que las contrapartes de Java EE correctamente son @Stateless session beans y @Singleton Beans se utilizan para configurar la aplicación en el inicio o la limpieza en el cierre o para contener objetos de toda la aplicación. ¿Es esto correcto?


Creo que Singleton en el uso de concurrencia no tendrá un rendimiento peor que el SLSB Pool, podría ser incluso mejor. El único problema es que si desea compartir algo entre subprocesos, necesita bloquearlo, y ese podría ser un gran problema de rendimiento. Entonces, en ese caso, un grupo de SLSB funciona mucho mejor, porque no es 100% singleton, hay más casos, uno se bloqueó, el otro aparece. De todos modos, si el bloqueo está en algunos recursos compartidos por todos los SLSB, el grupo no ayudará a ninguno de los dos.

En resumen, creo que Singleton es mejor que SLSB Pool, debería usarlo si puede. También es el ámbito predeterminado para los frijoles de primavera.

No soy un experto en JavaEE, eso es solo mi sensación, corríjame si me equivoco.


Creo que deberías usar el bean de sesión Singleton. Debido a que un servicio de inicio de sesión debe ser un servicio global y no necesita almacenar ningún estado para un usuario concreto o una invocación.


Debería optar por Singleton si tiene algún recurso que se mantendrá constante en toda la aplicación. Como cargar algunos datos de algún archivo o datos de referencia que no cambiarían a lo largo del ciclo de vida de la aplicación. De lo contrario, vaya para SLSB. El inconveniente de SLSB es que se crearían múltiples objetos, por lo que se ocuparía más memoria.


Imho yo respondería así:

"no se debe compartir ningún estado en la aplicación" me lleva a un bean sin estado debido a la frase "Para mejorar el rendimiento, puede elegir un bean de sesión sin estado ...".

Teniendo en cuenta que "se podría acceder a un único enterprise bean por varios subprocesos simultáneamente", tendría que usar singleton. Si lo hago bien, ni siquiera es posible acceder a un bean sin estado simultáneamente cuando se utiliza correctamente.

"No es necesario realizar ninguna tarea en el inicio o en el disparo" no me importaría. Si hay que hacer tareas para configurar correctamente un bean, entonces deben ser invocadas por un método @PostActivate.

Lógicamente concluiría su pregunta qué usar para @Singleton ya que pidió un acceso simultáneo. Por supuesto, tendrá que controlar manualmente la sincronización de los accesos en cualquier otro recurso (que no sean EJB).


Me gustaría ir a Stateless: el servidor puede generar muchas instancias del bean y procesar las solicitudes entrantes en paralelo.

Singleton suena como un posible cuello de botella: el valor predeterminado de @Lock es @Lock (WRITE) pero puede cambiarse a @Lock (READ) para los métodos bean o individuales.


Si está seguro de que no está compartiendo el estado entre los subprocesos, entonces un Singleton estará bien, en cuyo caso también debe anotar la clase con @ConcurrencyManagement( ConcurrencyManagementType.BEAN ) que permitirá que se ejecuten varios subprocesos al mismo tiempo.


de acuerdo con las especificaciones de ejb 3.1, página 110, capítulo 4.8.5 "Simultaneidad Singleton":

Es legal almacenar objetos Java EE que no admiten el acceso concurrente (por ejemplo, administradores de entidades, referencias de Stateful Session Bean) dentro del estado de instancia de bean Singleton. Sin embargo, es responsabilidad del desarrollador de Bean asegurar que no se acceda a estos objetos por más de un hilo a la vez.

y además, según la documentación del gestor de entidades de hibernación.

Un EntityManager es un objeto económico, no seguro para subprocesos, que se debe usar una vez, para un solo proceso de negocios, una sola unidad de trabajo, y luego descartarse.

Para mí, esto significa que nunca debe inyectar un EntityManager en un EJB singleton. Yo usaría un EJB singleton como reemplazo para un EJB sin estado solo si TODO lo que necesito implementar en esta clase es compatible con la concurrencia sin la necesidad de realizar un bloqueo / sincronización adicional. Como usted u otros programadores podrían perder este problema, tarde o temprano, desde su enfoque, personalmente prefiero no utilizar los EJBs singleton, excepto los problemas relacionados con el inicio o las características que pueden implementarse como unidades autónomas, independientemente de otros beans. En ese sentido, no parece recomendable inyectar, por ejemplo, EJB sin estado en Singletons. Al hacerlo, surge la pregunta sobre el punto en el tiempo, cuando el contenedor realiza la inyección del SLSB en el Singleton. De acuerdo con la especificación EJB 3.1, capítulo 4.8, la inyección de dependencia se realiza antes de que los clientes puedan acceder a la instancia del bean singleton. Entonces, el singleton obviamente se apegaría a la misma instancia de la SLSB, que parece convertirse en un singleton implícitamente, pero no parece haber ninguna garantía para eso. Al menos no pude encontrar nada en las especificaciones, por lo que el comportamiento puede ser impredecible o, en el mejor de los casos, específico del contenedor, que no es lo que la mayoría de la gente quiere.

Por lo tanto, solo inyectaría Singletons en Singletons o Singletons en SLSB, pero no al revés. Para el caso de una inyección de un Singleton en un Singleton, la especificación le ofrece la oportunidad de definir las dependencias entre los singletones para que el contenedor pueda inicializarlos en el orden correcto (consulte la especificación de ejb 3.1, capítulo 4.8.1 sobre la @ DependsOn anotación).


@Stateless le permitirá tener varias copias listas para procesar dentro de una JVM (tanto como lo permita la memoria y el tamaño de la agrupación) donde @Singleton solo hay una copia en una JVM, incluso si la única puede admitir múltiples subprocesos concurrentes en contra eso.

En términos de rendimiento, @Singleton sería mejor, siempre que los recursos que utiliza permitan un acceso de larga ejecución. Sin embargo, en un entorno distribuido a veces ocurren cosas malas, por ejemplo, la base de datos o los enlaces de red pueden fallar.

Con un bean @Stateless , el acceso es más breve. Además, si se produce un error, solo reaparecerá e intentará establecer una nueva conexión con el recurso. Si algo así sucede en un singleton, entonces depende del singleton que lo maneje sin requerir un reinicio de la aplicación, ya que @PostConstruct solo se llama una vez por JVM.

Preferiría un poco de tolerancia a fallos en comparación con el rendimiento para la mayoría de las situaciones, especialmente en sistemas sobre los que no tengo control.