开发者

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

开发者 https://www.devze.com 2023-02-02 03:54 出处:网络
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 @Singl

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

0

精彩评论

暂无评论...
验证码 换一张
取 消