Spring's singleton pattern bottom implementation Learning notes

Source: Internet
Author: User

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.

 PackageSpring; Public classSINGLETONWW {Private Static FinalSINGLETONWW instance=NewSingletonww (); //Private default constructor    PrivateSingletonww () {}//Static Factory Method     Public Staticsingletonww getinstance () {returninstance; }}

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:

 PackageSpring; Public classSINGLETONWW {Private StaticSINGLETONWW instance =NULL; //Private default constructor    PrivateSingletonww () {}//Static Factory Method     Public synchronized Staticsingletonww getinstance () {if(instance==NULL) {instance=NewSingletonww (); }            returninstance; }}

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.

 PackageSpring;ImportJava.util.HashMap; Public classSINGLETONWW {Private StaticHashMap Registry =NewHashMap ();  PublicSingletonww () {}//Static Factory Method     Public synchronized Staticsingletonww getinstance (String name) {if(Name! =NULL) {            if(Registry.get (name) = =NULL) {                Try{registry.put (name, Class.forName (name). newinstance ()); } 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 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 classAbstractbeanfactoryImplementsconfigurablebeanfactory{/*** Serves as a cache of bean instances, implemented in the same way as a single case registry*/         Private FinalMap singletoncache=NewHashMap ();  PublicObject Getbean (String name)throwsbeansexception{returnGetbean (Name,NULL,NULL); }      ...          PublicObject Getbean (String name,class requiredtype,object[] args)throwsbeansexception{//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 inspection of single-case registryObject sharedinstance=NULL; //code-locking synchronization blocks are used, similar in principle to synchronous methods, but this is more efficient          synchronized( This. Singletoncache) {sharedinstance= This. Singletoncache.get (Beanname); }            if(sharedinstance!=NULL){               ...               //returns the appropriate cache bean instancebean=getobjectforsharedinstance (name,sharedinstance); }Else{              ...              //get the definition of the beanRootbeandefinition mergedbeandefinition=getmergedbeandefinition (Beanname,false); ...              //based on the bean definition, this decision is based on a single-instance property switch that usually comes from a component configuration file//<bean id= "date" class= "Java.util.Date" scope= " singleton"/>//if it is a single case, do the following            if(Mergedbeandefinition.issingleton ()) {synchronized( This. Singletoncache) {                  //re-test the single-case registrySharedinstance= This. Singletoncache.get (Beanname); if(sharedinstance==NULL){                      ...                     Try {                        //To actually create a bean instanceSharedinstance=Createbean (Beanname,mergedbeandefinition,args); //registering a bean instance with a single case registryAddsingleton (beanname,sharedinstance); }Catch(Exception ex) {...}finally{                        ...                    } }} Bean=getobjectforsharedinstance (name,sharedinstance); }             //If you are a singleton, or Prototpye, create a new bean instance each time//<bean id= "date" class= "Java.util.Date" scope= " prototype"/>           Else{Bean=Createbean (Beanname,mergedbeandefinition,args); }      }      ...         returnBean; }      }   

In the source code, what we 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, and if the configuration information in the configuration file does not require a singleton, Spring returns an object instance in the same way as a new instance

Spring's singleton pattern bottom-up implementation learning notes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.