Singleton is a Creational Design Pattern with the following object structural:
The GoF (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) book describes this pattern as "Ensure a class has only one instance and provide a global point of access to it."
A Java class is considered a singleton if:
The GoF (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) book describes this pattern as "Ensure a class has only one instance and provide a global point of access to it."
A Java class is considered a singleton if:
·
it has one instance
·
provide a global point of access to it
Main aspects
that you should keep in mind is that a singleton classes are:
·
not unit testable
·
not abstractable
·
not extendable
In order to
respect the contract imposed by a singleton class you can write several
implementations:
·
the
singleton instance is created by an explicit call (in this case, you need to
synchronize the creation for multithreaded environment)
public class
FooSingleton {
private static FooSingleton instance;
// "hidden" constructor
private FooSingleton() {}
// obtain FooSingleton instance
public static synchronized FooSingleton
getInstance() {
if (instance == null){
instance = new FooSingleton();
}
return instance;
}
}
·
the
singleton instance is created at the same time you load the class (in this
case, there is no need to synchronize the creation)
public class
FooSingleton {
private final static FooSingleton instance=new
FooSingleton();
// "hidden" constructor
private FooSingleton() {}
// obtain FooSingleton instance
public static FooSingleton getInstance() {
return
instance;
}
}
·
use a
static block to obtain lazy initialization:
public class
FooSingleton {
private static FooSingleton instance=null;
static {
instance=new FooSingleton();
}
// "hidden" constructor
private FooSingleton() {}
// obtain FooSingleton instance
public static FooSingleton getInstance() {
return instance;
}
}
·
use double‐checked
locking - before locking on the singleton class and before the creation of the
object:
public class
FooSingleton {
private volatile FooSingleton instance;
// "hidden" constructor
private FooSingleton() {}
// obtain FooSingleton instance
public FooSingleton getInstance() {
if (instance == null) {
synchronized (FooSingleton.class) {
if (instance == null) {
instance
= new FooSingleton();
}
}
}
return
instance;
}
}
·
enum type
implementation:
public enum
FooSingletonEnum {
INSTANCE;
public void fooAction(){}
}
FooSingletonEnum
foo = FooSingletonEnum.INSTANCE;
But, Java EE
allows us to turn a class into a singleton via:
·
@Singleton
for EJB (javax.ejb.Singleton)
JSR-318
specification - Single thread safe and transactional shared instance. This is
useful for EJBs (enterprise services) and it is managed by the EJB container.
·
@Singleton
for CDI (javax.inject.Singleton)
JSR 330 specification - In CDI this is a pseudo-scope that
indicates that a bean has a single instance. 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. 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.
·
@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: JSF singleton vs application scoped managed bean - differences?
JSF uses singletons for different purposes. Some cases are mentioned below:
-the JSF entry point, FacesServlet
-the Application and lifecycle instances
-the JSF phase listeners
-the navigation and view handlers
Niciun comentariu :
Trimiteți un comentariu