单例模式不能被继承_Spring的单例实现原理
单例模式有饿汉模式、懒汉模式、静态内部类、枚举等方式实现,但由于以上模式的构造方法是私有的,不可继承,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的单例实现原理相关推荐
- spring 单例 获取多例的位_Spring 获取单例流程(一)
读完这篇文章你将会收获到 在 getBean 方法中, Spring 处理别名以及 factoryBean 的 name Spring 如何从多级缓存中根据 beanName 获取 bean Spri ...
- 懵了,Java枚举单例模式比DCL和静态单例要好???
点击关注公众号,实用技术文章及时了解 来源:liuchenyang0515.blog.csdn.net/article/ details/121049426 文章目录 双重校验锁单例(DCL) 为什么 ...
- 单例模式(Python中的单例类)
目录 一.单例模式的概述 二.单例模式的优缺点 三.在Python中,单例模式有以下几种实现方式 1.通过魔法方法__new__实现 2.通过模块的导入 3.通过装饰器实现 4.通过使用类实现 一.单 ...
- 以下哪个选项不是单例模式的优点_设计模式--单例
概述 单例模式(SingletonPattern),保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式有 3 个特点: 单例类只有一个实例对象: 该单例对象必须由单例类自行创建: 单例类 ...
- java 单例 dcl_java 中单例模式DCL的缺陷及单例的正确写法
1 前言 单例模式是我们经常使用的一种模式,一般来说很多资料都建议我们写成如下的模式: /** * Created by qiyei2015 on 2017/5/13. */ public class ...
- java单例注册表_Spring对单例的底层实现,单例注册表
public abstract class AbstractBeanFactory implementsConfigurableBeanFactory{/*** 充当了Bean实例的缓存,实现方式和单 ...
- 单例模式代码_设计模式之单例:程序员必知必会,举例子+代码示例,通俗易懂...
推荐学习 给力!啃烂这套"核心知识"+"高级面试",成功定级腾讯JavaT4 举个通俗的例子:我们电脑桌面上的一些软件快捷方式,我们可以创建多个这样的快捷方式, ...
- filter java 是单例的吗_JAVA 设计模式之 单例模式详解
单例模式:(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.单例模式是创建型模式.单例模式在现实生活中应用也非常广泛. 在 J2EE 标准中,S ...
- java单例设计模式_Java设计模式之单例模式详解
在Java开发过程中,很多场景下都会碰到或要用到单例模式,在设计模式里也是经常作为指导学习的热门模式之一,相信每位开发同事都用到过.我们总是沿着前辈的足迹去做设定好的思路,往往没去探究为何这么做,所以 ...
最新文章
- RISC-V会彻底改变计算吗?
- 前端文件path路由:基于base引用
- SPH(光滑粒子流体动力学)流体模拟实现三:Marching Cube算法(2)
- (6)FPGA面试技能提升篇(OpenCV)
- vivo又有新机跑分曝光 机海战术要来了?
- ISO/IEC 27002:2022中文版
- java合并pdf 追加页数_使用IText API将页码添加到具有不同页面大小的合并PDF
- 二维数组指针,指针数组与数组指针的区别,一看就懂
- 由南非世界杯想到IDC
- 全方位教你怎么看懂英国的车牌
- 如何通过网站域名查询服务器地址,如何根据域名查看服务器地址
- 网络:七层,HTTP应用层、TCP传输层、IP网络层,拔网线TCP还在,三次握手保证双向与减少因延时传输错误
- jsp mysql企业网站_JSP基于MySQL构建中小企业电子商务网站.pdf
- Web2与Web3开发的不同之处
- FastReport 分组按每组单独一页打印
- elementui实现表格单选功能
- 电脑监控软件有哪些?具体功能是什么
- linux如何修改机器名,简单修改Linux主机名
- 通过Consumer函数式接口,实现回调
- 为什么程序下在其他盘,c盘空间还是增多了?appdata文件夹有什么用途?
热门文章
- 2680 Problem F: Coin Game
- SharePoint Portal Server之常见问题
- php 己遏急背季磐,PHP防止SQL攻击教程
- springboot监听器_Spring Boot中文参考指南(2.1.6)23.5、应用程序事件和监听器
- android unity 关闭应用_Unity 之 唤起调用 Android 其它应用app的方法
- 微课|中学生可以这样学Python(例7.4):队列
- 微课|中学生可以这样学Python(例3.2):今天是今年的第几天
- torch各个版本镜像_如何解决在cuda上安装torch后torch.cuda.is_available()返回False
- php发布post到wordpress,PHP-如何将数据发布到wordpress插件?
- C语言:进制转换(整数、字符串)