Spring的单例实现原理

单例模式有饿汉模式、懒汉模式、静态内部类、枚举等方式实现,但由于以上模式的构造方法是私有的,不可继承,Spring为实现单例类可继承,使用的是单例注册表的方式。
什么是单例注册表呢,
1. 使用map实现注册表;
2. 使用protect修饰构造方法;
我们看一个例子:

Import java.util.HashMap;    
Public class RegSingleton{
    //使用一个map来当注册表
   Static private HashMap registry=new HashMap();    
   //静态块,在类被加载时自动执行    
    Static{    
     RegSingleton rs=new RegSingleton();    
     Registry.put(rs.getClass().getName(),rs);    
   }    
//受保护的默认构造函数,如果为继承关系,则可以调用,克服了单例类不能为继承的缺点    
Protected RegSingleton(){}    
//静态工厂方法,返回此类的唯一实例    
public static RegSingleton getInstance(String name){    
    if(name==null){    
      name=” RegSingleton”;    
    }if(registry.get(name)==null){    
      try{    
          registry.put(name,Class.forName(name).newInstance());    
       }Catch(Exception ex){ex.printStackTrace();}    
    }    
    Return (RegSingleton)registry.get(name);    
}    
}  

看下spring的源码:

public abstract class AbstractBeanFactory implements ConfigurableBeanFactory{    
   /**  
    * 充当了Bean实例的缓存,实现方式和单例注册表相同  
    */    
   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{    
      //对传入的Bean name稍做处理,防止传入的Bean name名有非法字符(或则做转码)    
      String beanName=transformedBeanName(name);    
      Object bean=null;    
      //手工检测单例注册表    
      Object sharedInstance=null;    
      //使用了代码锁定同步块,原理和同步方法相似,但是这种写法效率更高    
      synchronized(this.singletonCache){    
         sharedInstance=this.singletonCache.get(beanName);    
       }    
      if(sharedInstance!=null){    
         ...    
         //返回合适的缓存Bean实例    
         bean=getObjectForSharedInstance(name,sharedInstance);    
      }else{    
        ...    
        //取得Bean的定义    
        RootBeanDefinition mergedBeanDefinition=getMergedBeanDefinition(beanName,false);    
         ...    
        //根据Bean定义判断,此判断依据通常来自于组件配置文件的单例属性开关    
        //    
        //如果是单例,做如下处理    
        if(mergedBeanDefinition.isSingleton()){    
           synchronized(this.singletonCache){    
            //再次检测单例注册表    
             sharedInstance=this.singletonCache.get(beanName);    
             if(sharedInstance==null){    
                ...    
               try {    
                  //真正创建Bean实例    
                  sharedInstance=createBean(beanName,mergedBeanDefinition,args);    
                  //向单例注册表注册Bean实例    
                   addSingleton(beanName,sharedInstance);    
               }catch (Exception ex) {    
                  ...    
               }finally{    
                  ...    
              }    
             }    
           }    
          bean=getObjectForSharedInstance(name,sharedInstance);    
        }    
       //如果是非单例,即prototpye,每次都要新创建一个Bean实例    
       //    
       else{    
          bean=createBean(beanName,mergedBeanDefinition,args);    
       }    
}    
...    
   return bean;    
}    
}

你可能感兴趣的:(spring)