@Singleton vs @ApplicationScope
All those kinds of singletons (static
, @javax.inject.Singleton
, @javax.ejb.Singleton
and @javax.enterprise.context.ApplicationScoped
) are created once per JVM.
An object that is created once per user session must be annotated with @javax.enterprise.context.SessionScoped
so no, singletons will not be instantiated per user session.
Notice that there are two @Singleton
annotations, one in javax.inject
and the other in the javax.ejb
package. I'm referring to them by their fully-qualified names to avoid confusion.
The differences between all those singletons are subtle and I'm not sure I know all the implications, but a few come to mind:
@javax.ejb.Singleton
is managed by the EJB container and so it can handle transactions (@javax.ejb.TransactionAttribute
), read/write locking and time-outs (@javax.ejb.Lock
,@javax.ejb.AccessTimeout
), application startup (@javax.ejb.Startup
,@javax.ejb.DependsOn
) and so on.@javax.enterprise.context.ApplicationScoped
is managed by the CDI container, so you won't have the transaction and locking features that EJB has (unless you use a post-1.0 CDI that has added transactions), but you still have lots of nice things such as@javax.enterprise.inject.Produces
,@javax.annotation.PostConstruct
,@javax.inject.Named
,@javax.enterprise.inject.Disposes
(but many of these features are available to EJBs too).@javax.inject.Singleton
is similar to@ApplicationScoped
, except that there is no proxy object (clients will have a reference to the object directly). There will be less indirection to reach the real object, but this might cause some issues related to serialization (see this: http://docs.jboss.org/weld/reference/latest-2.2/en-US/html_single/#_the_singleton_pseudo_scope)- A plain static field is simple and just works, but it's controlled by the class loader so in order to understand how/when they are instantiated and garbage collected (if ever), you will need to understand how class loaders work and how your application server manages its class loaders (when restarting, redeploying, etc.). See this question for more details.
javax.inject.Singleton - When used on your bean, you have to implement writeResolve()
and readReplace
to avoid any serialization issues. Use it judiciously based on what your bean actually has in it.
javax.enterprise.context.ApplicationScoped - Allows the container to proxy the bean and take care of serialization process automatically. This is recommended to avoid unprecedented issues.
For More information refer this page number 45.