Spring中的设计模式-单例模式(转)

单例模式确保一个类在应用中只有一个实例

       我们以依赖注入创建bean实例为线索分析一下spring中单例模式。

       Spring的依赖注入(包括lazy-init方式)都是发生在AbstractBeanFactory的getBean里。getBean的doGetBean方法调用getSingleton进行bean的创建。lazy-init方式,在容器初始化时候进行调用,非lazy-init方式,在用户向容器第一次索要bean时进行调用。

带同步的单例模式

下面是单例模式的核心代码。

[java]  view plain  copy
  1. protected Object getSingleton(String beanName, boolean allowEarlyReference) {  
  2.   Object singletonObject = this.singletonObjects.get(beanName);  
  3.   if (singletonObject == null) {  
  4.    synchronized (this.singletonObjects) {  
  5.     singletonObject = this.earlySingletonObjects.get(beanName);  
  6.     if (singletonObject == null && allowEarlyReference) {  
  7.      ObjectFactory singletonFactory = this.singletonFactories.get(beanName);  
  8.      if (singletonFactory != null) {  
  9.       singletonObject = singletonFactory.getObject();  
  10.       this.earlySingletonObjects.put(beanName, singletonObject);  
  11.       this.singletonFactories.remove(beanName);  
  12.      }  
  13.     }  
  14.    }  
  15.   }  
  16.   return (singletonObject != NULL_OBJECT ? singletonObject : null);  
  17.  }  


     从上面代码可以看到,spring依赖注入时,使用了双重判断加锁的单例模式,首先从缓存中获取bean实例,如果为null,对缓存map加锁,然后再从缓存中获取bean,如果继续为null,就创建一个bean。这样双重判断,能够避免在加锁的瞬间,有其他依赖注入引发bean实例的创建,从而造成重复创建的结果。

      在这里Spring并没有使用私有构造方法来创建bean,而是通过singletonFactory.getObject()返回具体beanName对应的ObjectFactory来创建bean。我们一路跟踪下去,发现实际上是调用了AbstractAutowireCapableBeanFactory的doCreateBean方法,返回了BeanWrapper包装并创建的bean实例。

(ObjectFactory主要检查是否有用户定义的BeanPostProcessor后处理内容,并在创建bean时进行处理,如果没有,就直接返回bean本身)

 

见如下代码:

8行创建bean实例返回给BeanWrapper

30行addSingletonFactory增加beanName和ObjectFactory的键值对应关系。

[java]  view plain  copy
  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {  
  2.         // Instantiate the bean.  
  3.         BeanWrapper instanceWrapper = null;  
  4.         if (mbd.isSingleton()) {  
  5.             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  
  6.         }  
  7.         if (instanceWrapper == null) {  
  8.             instanceWrapper = createBeanInstance(beanName, mbd, args);  
  9.         }  
  10.         final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);  
  11.         Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);  
  12.   
  13.         // Allow post-processors to modify the merged bean definition.  
  14.         synchronized (mbd.postProcessingLock) {  
  15.             if (!mbd.postProcessed) {  
  16.                 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);  
  17.                 mbd.postProcessed = true;  
  18.             }  
  19.         }  
  20.   
  21.         // Eagerly cache singletons to be able to resolve circular references  
  22.         // even when triggered by lifecycle interfaces like BeanFactoryAware.  
  23.         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&  
  24.                 isSingletonCurrentlyInCreation(beanName));  
  25.         if (earlySingletonExposure) {  
  26.             if (logger.isDebugEnabled()) {  
  27.                 logger.debug("Eagerly caching bean '" + beanName +  
  28.                         "' to allow for resolving potential circular references");  
  29.             }  
  30.             addSingletonFactory(beanName, new ObjectFactory() {  
  31.                 public Object getObject() throws BeansException {  
  32.                     return getEarlyBeanReference(beanName, mbd, bean);  
  33.                 }  
  34.             });  
  35.         }....  


getEarlyBeanReference获取bean的所有后处理器,并进行处理。如果是SmartInstantiationAwareBeanPostProcessor类型,就进行处理,如果没有相关处理内容,就返回默认的实现。

[java]  view plain  copy
  1. protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {  
  2.         Object exposedObject = bean;  
  3.         if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {  
  4.             for (BeanPostProcessor bp : getBeanPostProcessors()) {  
  5.                 if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {  
  6.                     SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;  
  7.                     exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);  
  8.                     if (exposedObject == null) {  
  9.                         return exposedObject;  
  10.                     }  
  11.                 }  
  12.             }  
  13.         }  
  14.         return exposedObject;  
  15.     }  


另外,在Spring的其他代码中也有使用的单例模式,如AOP的切点定义中。 

公有静态成员,私有构造函数的单例模式

[java]  view plain  copy
  1. class TruePointcut implements Pointcut, Serializable {  
  2.       
  3.     private static final TruePointcut INSTANCE = new TruePointcut();  
  4.       
  5.     /** 
  6.      * Enforce Singleton pattern. 
  7.      */  
  8.     private TruePointcut() {  
  9.     }  
  10.   
  11.     ....  
  12.        public static TruePointcut getInstance(){  
  13.         return INSTANCE;  
  14.       }  
  15. }  

上面的代码可以改成:静态工厂方法的单例模式

[java]  view plain  copy
  1. class TruePointcut implements Pointcut, Serializable {  
  2.       
  3.     private static final TruePointcut INSTANCE = new TruePointcut();  
  4.       
  5.     /** 
  6.      * Enforce Singleton pattern. 
  7.      */  
  8.     private TruePointcut() {  
  9.     }  
  10.   
  11.     ....  
  12.        public static TruePointcut getInstance(){  
  13.         return INSTANCE;  
  14.       }  
  15. }  

或者改成: 用枚举实现 单例模式

[java]  view plain  copy
  1. enum TruePointcut implements Pointcut, Serializable {  
  2.       
  3.     INSTANCE ;  
  4. ...      
  5.   
  6. }  
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页