Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Singleton vs @ApplicationScope

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 :)

like image 717
dognose Avatar asked Nov 09 '14 19:11

dognose


People also ask

What is difference between singleton and application scope?

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.

Is ApplicationScoped a singleton?

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.

What does the @ApplicationScoped annotation indicate?

The @ApplicationScoped annotation indicates that the managed bean will be available throughout the lifetime of the application.

What is application scoped in Java?

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.


2 Answers

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.
like image 193
marcus Avatar answered Sep 17 '22 15:09

marcus


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.

like image 34
srk Avatar answered Sep 21 '22 15:09

srk