Solución:
Todos esos tipos de singletons (static
, @javax.inject.Singleton
, @javax.ejb.Singleton
y @javax.enterprise.context.ApplicationScoped
) son creados una vez por JVM.
Un objeto que se crea una vez por sesión de usuario debe anotarse con @javax.enterprise.context.SessionScoped
así que no, no se crearán instancias de singletons por sesión de usuario.
Note que hay dos @Singleton
anotaciones, una en javax.inject
y el otro en el javax.ejb
paquete. Me refiero a ellos por sus nombres completos para evitar confusiones.
Las diferencias entre todos esos singletons son sutiles y no estoy seguro de conocer todas las implicaciones, pero me vienen a la mente algunas:
-
@javax.ejb.Singleton
es administrado por el contenedor EJB y, por lo tanto, puede manejar transacciones (@javax.ejb.TransactionAttribute
), bloqueo de lectura / escritura y tiempos de espera (@javax.ejb.Lock
,@javax.ejb.AccessTimeout
), inicio de la aplicación (@javax.ejb.Startup
,@javax.ejb.DependsOn
) etcétera. -
@javax.enterprise.context.ApplicationScoped
es administrado por el contenedor CDI, por lo que no tendrá las funciones de transacción y bloqueo que tiene EJB (a menos que use un CDI posterior a 1.0 que haya agregado transacciones), pero aún tiene muchas cosas buenas como@javax.enterprise.inject.Produces
,@javax.annotation.PostConstruct
,@javax.inject.Named
,@javax.enterprise.inject.Disposes
(pero muchas de estas funciones también están disponibles para los EJB). -
@javax.inject.Singleton
es parecido a@ApplicationScoped
, excepto que no hay ningún objeto proxy (los clientes tendrán una referencia al objeto directamente). Habrá menos indirección para llegar al objeto real, pero esto podría causar algunos problemas relacionados con la serialización (consulte esto: http://docs.jboss.org/weld/reference/latest-2.2/en-US/html_single/#_the_singleton_pseudo_scope ) - Un campo estático simple es simple y simplemente funciona, pero está controlado por el cargador de clases, por lo que para comprender cómo / cuándo se instancian y recolectan basura (si es que alguna vez), necesitará comprender cómo funcionan los cargadores de clases y cómo su servidor de aplicaciones gestiona sus cargadores de clases (al reiniciar, volver a implementar, etc.). Consulte esta pregunta para obtener más detalles.
javax.inject.Singleton – Cuando se usa en su bean, debe implementar writeResolve()
y readReplace
para evitar problemas de serialización. Úselo con prudencia en función de lo que realmente tiene su frijol.
javax.enterprise.context.ApplicationScoped – Permite que el contenedor haga proxy del bean y se encargue del proceso de serialización automáticamente. Esto se recomienda para evitar problemas sin precedentes.
Para obtener más información, consulte esta página número 45.