Spring 设计模式之单例

来源:互联网 发布:金锐盘开票软件 编辑:程序博客网 时间:2024/04/30 11:22
 

Spring 设计模式之单例

分类: Spring2010-01-28 10:25 1512人阅读 评论(0) 收藏 举报
spring设计模式objectbeanreturningstring

为了更深入的了解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也是一样的道理.

0 0
原创粉丝点击