单例模式有饿汉模式、懒汉模式、静态内部类、枚举等方式实现,但由于以上模式的构造方法是私有的,不可继承,Spring为实现单例类可继承,使用的是单例注册表的方式。

什么是单例注册表呢:

Spring是通过注册表实现单例的,Ioc容器维护了一个bean表格,当需要一个单例bean时,从表格中获取,没有获取到的,向表格注册一个新的bean。
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的单例实现原理相关推荐

  1. spring 单例 获取多例的位_Spring 获取单例流程(一)

    读完这篇文章你将会收获到 在 getBean 方法中, Spring 处理别名以及 factoryBean 的 name Spring 如何从多级缓存中根据 beanName 获取 bean Spri ...

  2. 懵了,Java枚举单例模式比DCL和静态单例要好???

    点击关注公众号,实用技术文章及时了解 来源:liuchenyang0515.blog.csdn.net/article/ details/121049426 文章目录 双重校验锁单例(DCL) 为什么 ...

  3. 单例模式(Python中的单例类)

    目录 一.单例模式的概述 二.单例模式的优缺点 三.在Python中,单例模式有以下几种实现方式 1.通过魔法方法__new__实现 2.通过模块的导入 3.通过装饰器实现 4.通过使用类实现 一.单 ...

  4. 以下哪个选项不是单例模式的优点_设计模式--单例

    概述 单例模式(SingletonPattern),保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式有 3 个特点: 单例类只有一个实例对象: 该单例对象必须由单例类自行创建: 单例类 ...

  5. java 单例 dcl_java 中单例模式DCL的缺陷及单例的正确写法

    1 前言 单例模式是我们经常使用的一种模式,一般来说很多资料都建议我们写成如下的模式: /** * Created by qiyei2015 on 2017/5/13. */ public class ...

  6. java单例注册表_Spring对单例的底层实现,单例注册表

    public abstract class AbstractBeanFactory implementsConfigurableBeanFactory{/*** 充当了Bean实例的缓存,实现方式和单 ...

  7. 单例模式代码_设计模式之单例:程序员必知必会,举例子+代码示例,通俗易懂...

    推荐学习 给力!啃烂这套"核心知识"+"高级面试",成功定级腾讯JavaT4 举个通俗的例子:我们电脑桌面上的一些软件快捷方式,我们可以创建多个这样的快捷方式, ...

  8. filter java 是单例的吗_JAVA 设计模式之 单例模式详解

    单例模式:(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.单例模式是创建型模式.单例模式在现实生活中应用也非常广泛. 在 J2EE 标准中,S ...

  9. java单例设计模式_Java设计模式之单例模式详解

    在Java开发过程中,很多场景下都会碰到或要用到单例模式,在设计模式里也是经常作为指导学习的热门模式之一,相信每位开发同事都用到过.我们总是沿着前辈的足迹去做设定好的思路,往往没去探究为何这么做,所以 ...

最新文章

  1. RISC-V会彻底改变计算吗?
  2. 前端文件path路由:基于base引用
  3. SPH(光滑粒子流体动力学)流体模拟实现三:Marching Cube算法(2)
  4. (6)FPGA面试技能提升篇(OpenCV)
  5. vivo又有新机跑分曝光 机海战术要来了?
  6. ISO/IEC 27002:2022中文版
  7. java合并pdf 追加页数_使用IText API将页码添加到具有不同页面大小的合并PDF
  8. 二维数组指针,指针数组与数组指针的区别,一看就懂
  9. 由南非世界杯想到IDC
  10. 全方位教你怎么看懂英国的车牌
  11. 如何通过网站域名查询服务器地址,如何根据域名查看服务器地址
  12. 网络:七层,HTTP应用层、TCP传输层、IP网络层,拔网线TCP还在,三次握手保证双向与减少因延时传输错误
  13. jsp mysql企业网站_JSP基于MySQL构建中小企业电子商务网站.pdf
  14. Web2与Web3开发的不同之处
  15. FastReport 分组按每组单独一页打印
  16. elementui实现表格单选功能
  17. 电脑监控软件有哪些?具体功能是什么
  18. linux如何修改机器名,简单修改Linux主机名
  19. 通过Consumer函数式接口,实现回调
  20. 为什么程序下在其他盘,c盘空间还是增多了?appdata文件夹有什么用途?

热门文章

  1. 2680 Problem F: Coin Game
  2. SharePoint Portal Server之常见问题
  3. php 己遏急背季磐,PHP防止SQL攻击教程
  4. springboot监听器_Spring Boot中文参考指南(2.1.6)23.5、应用程序事件和监听器
  5. android unity 关闭应用_Unity 之 唤起调用 Android 其它应用app的方法
  6. 微课|中学生可以这样学Python(例7.4):队列
  7. 微课|中学生可以这样学Python(例3.2):今天是今年的第几天
  8. torch各个版本镜像_如何解决在cuda上安装torch后torch.cuda.is_available()返回False
  9. php发布post到wordpress,PHP-如何将数据发布到wordpress插件?
  10. C语言:进制转换(整数、字符串)