首页 > 代码库 > 单例模式之新的想法

单例模式之新的想法

前几天被问到了单例模式对构造函数有什么要求吗?答曰:没什么要求吧?

回来查了下具体的资料才发现,原来单例模式的实现private 的一个构造函数,目的是不让这个单例的类能够new一个对象出来。

思考了下,其实不加应该问题也不大,毕竟如果代码上都是一个人在写的话,其实这种问题还是可以规避的。但是又发现了其他新的一些想法。

先说下以前写的单例吧,其实也很简单,无非就是一个private static然后用getInstance返回,现在感觉想法确实有点幼稚。

 

上面说的那个private 的构造函数就不提了,个人感觉有当然最好,但是无也未尝不可。

贴一段spring的源码看看spring的sigleton如何写的先

/**
	 * Return the (raw) singleton object registered under the given name.
	 * <p>Checks already instantiated singletons and also allows for an early
	 * reference to a currently created singleton (resolving a circular reference).
	 * @param beanName the name of the bean to look for
	 * @param allowEarlyReference whether early references should be created or not
	 * @return the registered singleton object, or {@code null} if none found
	 */
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}


singletonObjects 是单例类中存储当前单例对象的一个Map,在获取单例的时候如果能取到则直接返回,如果没有取到则加锁产生一个对象返回。

按照spring的做法,对于配置文件中的类进行注册到singletonObjects 中

代码如下:

/**
	 * Add the given singleton object to the singleton cache of this factory.
	 * <p>To be called for eager registration of singletons.
	 * @param beanName the name of the bean
	 * @param singletonObject the singleton object
	 */
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

然后在使用的时候根据singletonObjects 进行查询并返回对应的对象。