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 prox开发者_Go百科ied, and @Singleton
is not.
Can I just change my @Singleton
bean to @ApplicationScoped
? Can @ApplicationScoped
bean have two (or more) instances?
@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.
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
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.
@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.
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
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
精彩评论