Singleton mode also belongs to the creation mode, the so-called Singleton, as the name implies, refers to a single instance, that is, to ensure that a class has only one instance.
The singleton pattern has the following characteristics:
①
A singleton class can have only one instance
Ii
The Singleton class must create its own unique instance
③
The Singleton class must provide this instance to all other objects
Let's write a simple example of a singleton pattern.
Package spring;
public class Singletonww {
private static final Singletonww instance=new singletonww ();
Private default constructor private
Singletonww () {}
//Static factory method public
static SINGLETONWW getinstance () {
return instance;
}
}
As you can see, when this class is loaded, the static variable instance is initialized, when the private constructor of the class is called, and the Singleton class's unique instance is created.
It is important to note that because the constructor is private, the class cannot be inherited
There is also a way to implement a singleton pattern:
Package spring;
public class Singletonww {
private static SINGLETONWW instance = null;
Private default constructor private
Singletonww () {}
//Static factory method public
synchronized static SINGLETONWW getinstance () {
if (instance==null) {
instance = new Singletonww ();
}
return instance;
}
}
The difference between this and the first is that the instance is not instantiated directly, but only when the static factory method is called, and the Static factory method is synchronized to handle the multi-threaded concurrency environment.
There are also two very interesting names in these two ways: the first is called the A Hungry man, the second is the lazy type single case.
The A Hungry man-type Singleton will instantiate itself when it is loaded, if it is slightly worse than the lazy one in terms of resource utilization efficiency. But from the angle of speed and reaction time, it is slightly better than the lazy type.
Unfortunately, lazy-type singleton classes cannot be inherited.
We overcome the disadvantage that the first two types of singleton cannot be inherited, and we can use another special singleton pattern, which is called a singleton registry.
Package spring;
Import Java.util.HashMap;
public class Singletonww {
private static HashMap registry = new HashMap ();
Public Singletonww () {}
//Static factory method public
synchronized static SINGLETONWW getinstance (String name) {
if (name ! = null) {
if (registry.get (name) = = null) {
try {
registry.put (name, Class.forName (name). newinstance ()); c10/>} catch (Exception ex) {
ex.printstacktrace ();
}
} else {
return (SINGLETONWW) Registry.get ( name);
}
}
return null;
}
}
Let's take a look at the singleton implementation in spring, when we try to get an instance of a class from the spring container, by default, spring is created in singleton mode.
<bean id= "Date" class= "Java.util.Date"/> |
<bean id= "Date" class= "Java.util.Date" scope= "singleton"/> (Spring2.0 support only) |
<bean id= "Date" class= "Java.util.Date" singleton= "true"/> |
The three ways to create objects are exactly the same, and the container returns a singleton reference to the date class to the customer. So what if I don't want to use the default singleton mode and I want to get a new object every time I request it? It's easy to set the scope property value to prototype (prototype).
<bean id= "Date" class= "Java.util.Date" scope= "prototype"/> |
With the above configuration information, spring will return a new object instance to the client each time. So spring to the basic implementation of the Singleton, in the end is the A hungry man-type singleton or lazy-type single case. Oh, not at all. The spring framework's support for Singleton is implemented using a single-case registry, with the following source code:
Public abstract class Abstractbeanfactory implements configurablebeanfactory{/** * acts as a cache of bean instances, implementing the
The same as the single-case Registry */private final Map singletoncache=new HashMap ();
Public Object Getbean (String name) throws beansexception{return Getbean (name,null,null);
} ... public Object Getbean (String name,class requiredtype,object[] args) throws beansexception{
The incoming bean name is handled slightly to prevent the incoming bean name from having illegal characters (or transcoding) String beanname=transformedbeanname (name);
Object Bean=null;
Manual detection of single-case registry Object Sharedinstance=null; Code locking synchronization blocks are used, similar in principle to synchronous methods, but this is more efficient synchronized (This.singletoncache) {Sharedinstance=this.single
Toncache.get (Beanname); } if (Sharedinstance!=null) {...//returns the appropriate cache bean instance Bean=getobjectfor
Sharedinstance (name,sharedinstance);
}else{ ...//Get the definition of bean rootbeandefinition mergedbeandefinition=getmergedbeandefinition (beanname,f
Alse); ...//According to the Bean definition, this decision is based on a singleton property switch that usually comes from a component configuration file//<bean id= "date" class= "java.util.Date" scope= "si Ngleton "/>//If it is a singleton, do the following if (Mergedbeandefinition.issingleton ()) {Synchroni Zed (This.singletoncache) {//re-detects the Singleton registry Sharedinstance=this.singletoncache.get (Beanname
);
if (sharedinstance==null) {... try {//really create bean instance
Sharedinstance=createbean (Beanname,mergedbeandefinition,args);
Register the Bean Instance Addsingleton (beanname,sharedinstance) to the Singleton registry; }catch (Exception ex) {...}
Finally{...} }} bean=getobjectforsharedinstance (Name,sharedinstance); }//If it is a singleton, i.e. Prototpye, create a new bean instance each time//<bean id= "date" class= "Java.util.Date" scope= "Prototy
PE "/> else{bean=createbean (Beanname,mergedbeandefinition,args);
}} ... return bean; }
}
Just in the source code, what you really want to remember is that spring's creation of bean instances is implemented in a single-instance registry, and this registry cache is a HashMap object, if the configuration information in the configuration file does not require a singleton, Spring returns an object instance in the form of a new instance