Java设计模式学习笔记:单例模式(三)

上一篇文章介绍了单例模式的双重检测机制以及阻止通过反射破坏单例,传送门如下:

Java设计模式学习笔记:单例模式(二)

今天继续研究单例模式的几种高级模式,比如在Spring的 IOC机制中,是怎么来实现单例模式的?都知道IOC的意思是控制反转,通过IOC容器来管理Bean,当然也包括了Bean的实例化,他是怎么实现单例模式的呢?代码如下:

public class ContainerSingleton {

	private ContainerSingleton() {}
	//定义一个容器
	private static Map<String, Object> ioc = new ConcurrentHashMap<String, Object>();
	
	public static Object getInstance(String className) {
		
		Object instance = null;
		if(!ioc.containsKey(className)) {
			//如果是第一次进入,就创建一个实例,并且放到容器中
			try {
				instance = Class.forName(className).newInstance();
				ioc.put(className, instance);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return instance;
		} else {
			return ioc.get(className);
		}
	}
	
}

测试代码:

public static void main(String[] args) {
		
		Object instance1 = ContainerSingleton.getInstance("com.rq.pattern.TestVO");
		Object instance2 = ContainerSingleton.getInstance("com.rq.pattern.TestVO");
		System.out.println(instance1==instance2);
	}
}

运行结果:

true

这里看到,通过这种方式,可以实现单例模式,那么会被反射的方式破坏吗?从技术上说,是可以的,测试代码如下:

public static void main(String[] args) {
		
//		Object instance1 = ContainerSingleton.getInstance("com.rq.pattern.TestVO");
//		Object instance2 = ContainerSingleton.getInstance("com.rq.pattern.TestVO");
//		System.out.println(instance1==instance2);
		
		//测试通过反射破坏容器式单例
		Class<?> clazz =  ContainerSingleton.class;
		try {
			Constructor<?> c = clazz.getDeclaredConstructor(null);
			c.setAccessible(true);
			Object newInstance1 = c.newInstance();
			Object newInstance2 = c.newInstance();
			System.out.println(newInstance1);
			System.out.println(newInstance2);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行结果为:

com.rq.pattern.ContainerSingleton@6d06d69c
com.rq.pattern.ContainerSingleton@7852e922

可以看到,这种单例模式是可以被反射强制破坏的,那么为什么Spring的IOC还是要用这种方式来实现单例呢?可以这么理解:

因为IOC容器是一个生态,实例化是由IOC容器来管理的,他只负责他管理的单例是高效且线程安全的,在容器启动时就初始化了,后面只是调用,所以不存在线程安全的问题,不对他管理的生态外的负责,比如,在IOC中管理的类,你可以通过new的方式创建或者通过反射强制访问,代码编译不会报错,但是你无法使用new出来的对象。

Over。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值