For a project I need to have a unique ID generator. So I thought about a Singleton with synchronized methods.
Since a Singleton following the traditional Singleton pattern (private static instance
) is shared accross Sessions, I'm wondering if the @Singleton
Annotation is working the same way?
The documentation says: Identifies a type that the injector only instantiates once.
Does it mean, that a @Singleton
will be independent per User Session
(which is bad for an id-generator)? Should I prefer an old school
Singleton with Class.getInstance()
over an Injection of an @Singleton
-Bean?
Or should I use neither nor and provide the Service within an @ApplicationScoped
bean?
it musst be guaranteed that only ONE thread, independent of the user session can access the method to generate the next id. (It's not solvable with auto-increment database ids)
Edit: JSF 2.2, CDI and javax.inject.*
i'm talking about :)
When beans are application scoped, the same instance of the bean is shared across multiple servlet-based applications running in the same ServletContext, while singleton scoped beans are scoped to a single application context only.
inject. Singleton ), not JSR-299 managed beans in a built-in scope called Singleton. You might find in your server that @ApplicationScoped is one-per EAR or one-per WAR/EJB-JAR as it is not clear in the specification, but you should definitely not expect it to be one per JVM.
The @ApplicationScoped annotation indicates that the managed bean will be available throughout the lifetime of the application.
Description. @javax.enterprise.context.ApplicationScoped. A single bean instance is used for the application and shared among all injection points. The instance is created lazily, i.e. once a method is invoked upon the client proxy. @javax.inject.Singleton.
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)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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With