The singleton pseudo-scope ensures a single instance
of the bean
Besides the
dependent pseudo-scope, we also have the singleton pseudo-scope. As its name
suggest, a bean annotated with @Singleton (javax.inject.Singleton) is
instantiated only once. This scope is available only in CDI and is a
non-contextual scope. All CDI scopes, except this one (and @Dependent),
are known as normal scopes.
A normal
scope is a scope annotated with @NormalScope. These are contextual scopes
having a client proxy. Contextual scopes implements Contextual interface
which provides operations to create and destroy contextual instances of a
certain type (create()
and destroy()).
During
create() and destroy() the Contextual interface uses the CreationalContext
operations, push()
and release().
Contextual instances with a particular scope of any contextual type are
obtained via Context
interface operations (e.g. get()).
A
pseudo-scope is a scope annotated with @Scope. So, dependent scope is a
pseudo-scope. This is a non-contextual scope with no client proxy. Well, the "no client proxy" part should
be highlighted, ... and it is! CDI managed beans can be successfully used in
JSF, but there is a problem with CDI managed beans annotated with @Singleton.
They don't use proxy objects! Since there is a direct reference instead of a
proxy we have some serialization issues. When singleton scoped beans are
injected into client beans, the client beans will get a direct reference to the
injected bean. So, if client bean is Serializable (e.g. SessionScoped)
it must ensure that the injected singleton bean serialization is accomplished
correctly.
In order to keep the singleton state, we need
to:
·
having the singleton bean implement writeResolve()
and readReplace()
(as defined by the Java serialization specification),
·
make sure the client keeps only a transient
reference to the singleton bean, or
·
give the client a reference of type Instance<X>
where X
is the bean type of the singleton bean.
Fortunately,
we can avoid @Singleton
and still obtain the desired functionality. The answer relies in application
scope:
@ApplicationScoped for CDI (javax.enterprise.inject.ApplicationScoped)
JSR 229
specification - The CDI application scope which guarantee that the class is
instantiated only once. This is preferable because is much simpler to develop,
test and maintain. So, when CDI is available, use this for having a singleton
"surrogate" that provides a single instance and application scoped
data.
@ApplicationScoped for JSF (javax.faces.bean.ApplicationScoped)
JSR 314
specification - The JSF application scope which guarantee that the class is
instantiated only once - JSF as framework guarantee that only one instance will
be created and reused during web application's lifetime. Again, this is
preferable because is much simpler to develop, test and maintain.
See you in
the next post about the DeltaSpike grouped conversation scope.
Niciun comentariu :
Trimiteți un comentariu