为了更深入的了解Spring的架构体系,最近研读Spring源码进行分析,发现Spring的单例模式是这样子实现的:
<bean id="date" class="cn.framework.service.Sing" scope="singleton"/>
Spring是通过以上配置为单例模式,当然Spring默认就是单例模式.
那么Spring的底层是如何实现单例模式的呢? Java虽然有自动回收机制,而且自动回收机制也在不断的增强,但现在的对象创建和消除是
非常耗费资源的,以下是对Spring单例模式的分析,其实我们平时在写代码的时候也可以借用其单例模式:
代码数千,获如一条长龙,而关键却只是那“点睛”那一笔.
我们平时调用最多的就是getBean(String name),我们不管他是singleton还是property,接口是一致的.Spring是通过BeanFactory
这个接口实现的,之所谓为接口,只是为对外开放的端口,哪些方法开放,哪些方法不开发,完全由接口定义. 接下来我们来看AbstractBeanFactory,这是这个引用BeanFactory接口的抽象类。为什么用抽象类,之所谓为抽象,只是对现有对象的抽取,通过抽象类我们可以看到整个BeanFactory的蓝图,而具体的实现则交给子类.以下是AbstractBeanFactory的源码解析:
这是我们平常调用方法.
public Object getBean(String name) throws BeansException {
return getBean(name, null, null);
}这是方法的实现
public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException {
final String beanName = transformedBeanName(name);//去年前缀
Object bean = null;// 确认单例cache 有没有注册.单例使用ConcurrentHashMap来存储,多线程同步.[HashMap的多线程实现]
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {//如果有人在操作这个bean实例
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
/**如果是工厂,则返回工厂里面的对象,如果是对象,则直接返回该对象*/
if (containsBeanDefinition(beanName)) {//如果包含这个beanName的定义.
RootBeanDefinition mbd = getMergedBeanDefinition(beanName, false);//得到这个bean的定义
bean = getObjectForBeanInstance(sharedInstance, name, mbd);
//因为这个类可能是一个工厂类,所以我们还需要一个方法判断下,如果是工厂类的话,那么它应该返回一个产品
}
else {
bean = getObjectForBeanInstance(sharedInstance, name, null);
}
}这里的方法很简单,就是红色部门代码,外部调用时,返回这个单例对象。
/**
* 返回singleton对象实例
*/
public Object getSingleton(String beanName) {
Object singletonObject = this.singletonObjects.get(beanName);
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
/**
* 返回singleton对象实例
*/protected Object getObjectForBeanInstance(Object beanInstance, String name, RootBeanDefinition mbd) {
// Don't let calling code try to dereference the
// bean factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}boolean shared = (mbd == null || mbd.isSingleton());
Object object = beanInstance;if (beanInstance instanceof FactoryBean) {
。。。
}return object;
}这里两个方法更简单,第一个从Map中取出这个对象,第一个直接返回这个对象.
当然我这里点的只是冰山一角,比如在Spring初始化的时候如何,如何初始化为单例类,如何初始化为多例类等等还有很多。聪明的人都能够举一反三,既然我们取Singleton是从Map里面取,那么Spring在读取配置文件到BeanDefinition[Bean定义],再Proccesor到Map也是一样的道理.