What is the difference between @ApplicationScoped and @Singleton scopes in CDI?

JavaScopeCdi

Java Problem Overview


In CDI there is the @ApplicationScoped and the (javax.inject) @Singleton pseudo-scope. What is the difference between them? Besides the fact that @ApplicationScoped is proxied, and @Singleton is not.

Can I just change my @Singleton bean to @ApplicationScoped? Can @ApplicationScoped bean have two (or more) instances?

Java Solutions


Solution 1 - Java

@Singleton is not part of the CDI specification. It is part of EJB and javax.inject (JSR-330). It is not mentioned in the spec what is its behaviour, so you can only rely on what's written in the Weld documentation.

Solution 2 - Java

in short: You can even mix it (@Singleton and @ApplicationScoped) and it makes sense in some scenarios. (and works as expected in mine!)

Additionally to the other answers so far I'd like to add some more points for clarification in real world scenarios.

For me this question developed out of How do I force an application-scoped bean to instantiate at application startup? In some discussion there I stated this and can't find a valid argument against it so far:

> In a lot of real-life scenarios/setups I would say it's hard to > definitely say - from an abstract/modelling point of view - whether > something is (or will become/be treated like) an EJB or an application-scoped managed bean.

(debatable but not conclusive) arguments (from my point of view) against it so far: (@BalusC and all others: I'd like to see them beeing conclusive, but if not, the above may hold true and nevertheless the arguments may still help the reader to get the differences/advantages/disadvantages/ bad/good practices)

EJB vs. Managed Bean

> BalusC: That's an EJB not a managed bean, which is quite different. EJBs run in backend and managed beans in frontend. EJBs run in transactional context too. [...] You just confused enterprise beans with managed beans and I just pointed out that.

but:

> me: I think you are not quite correct and overstating the meaning/usage and it looks debatable to me. http://en.wikipedia.org/wiki/Enterprise_JavaBeans

> Enterprise JavaBeans (EJB) is a managed, server software for modular construction of enterprise software, and one of several Java APIs. EJB is a server-side software component that encapsulates the business logic of an application. > > Types of Enterprise Beans > > Session Beans [3] that can be either "Stateful", "Stateless" or "Singleton" [...] > > Message Driven Beans [...]

... which still holds true in my case.

Singleton EJB vs. Application Scoped Bean

Locking

> BalusC: A singleton EJB isn't the same as an application scoped bean. A singleton EJB is read/write locked and thus potentially inefficient/overconvoluted for the task you had in mind. Long story short: Grab a good Java EE book and learn to use the right tool for the job. One way definitely isn't the other way. That it works doesn't mean that it's the right tool. A sledgehammer is capable of fastening a screw, but it isn't necessarily the right tool to that :)

but:

(I can't see the sledgehammer here - sorry ...) It's good to know the locking defaults (I was not aware of it), but this seems to be incorrect again: Oracle Java EE 6 Tutorial on Managing Concurrent Access in a Singleton Session Bean

> When creating a singleton session bean, concurrent access to the singleton’s business methods can be controlled in two ways: container-managed concurrency and bean-managed concurrency. [...]

> Although by default, singletons use container-managed concurrency, the @ConcurrencyManagement(CONTAINER) annotation may be added at the class level of the singleton to explicitly set the concurrency management type

Solution 3 - Java

Usually when you want to have only one instance of some object you probably should use @ApplicationScoped annotation - such object is proxied and thus can even be properly serialized out-of-the-box.

On the other hand, there are also many cases, where you want only one instance of the class, but such class cannot be proxied (e.g. because of being final) - then @Singleton is a rescue. Because Singleton is a pseudo-scope and is not being proxied like any "normal" scope.

Solution 4 - Java

@Singleton in JSR-299 refers to Singleton session beans (javax.ejb.Singleton, not javax.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.

Solution 5 - Java

There is one more difference: @Singleton is not bean defining annotations, as the Singleton scope is not a normal scope. Then @ApplicationScoped is bean defining annotations.

With CDI 1.1 spec: When application in discovery-mode = annotated, Weld does not identify beans with @Singleton and not loaded this

Solution 6 - Java

One of the major differences that you can write your class with default constructor has private access modifier when using javax.inject.Singleton, but your class should have default constructor with at least default access modifier when using javax.enterprise.context.ApplicationScoped and this is JBOSS 6.1 GA Final implementation

Solution 7 - Java

I know this is an old post, but it's a question I get asked about quite often.

IMHO, go to the source -> https://www.javadoc.io/doc/jakarta.enterprise/jakarta.enterprise.cdi-api/latest/jakarta/enterprise/context/ApplicationScoped.html

https://www.javadoc.io/doc/jakarta.inject/jakarta.inject-api/latest/jakarta/inject/Singleton.html

https://quarkus.io/guides/cdi-reference#lazy_by_default provides a nice reference that compares the two in terms of practical usage.

(It also helps to note that in this last case, Quarkus creates the no-args constructor for you to meet the requirements for CDI beans, so you don't need to DIY or Lombok-it.)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionamorfisView Question on Stackoverflow
Solution 1 - JavaBozhoView Answer on Stackoverflow
Solution 2 - JavaAndreas CovidiotView Answer on Stackoverflow
Solution 3 - JavaG. DemeckiView Answer on Stackoverflow
Solution 4 - JavacovenerView Answer on Stackoverflow
Solution 5 - JavavigorView Answer on Stackoverflow
Solution 6 - Javauser1017344View Answer on Stackoverflow
Solution 7 - Javaedmangini76View Answer on Stackoverflow