由Spring框架中的单例模式想到的

来源:互联网 发布:阿里云备案要多长时间 编辑:程序博客网 时间:2024/05/16 03:53

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例

注:Spring源码的版本4.3.4

Spring依赖注入Bean实例默认是单例的,我们由此展开。

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

同步线程安全的单例核心代码:

/**     * 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);    }

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

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

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

见如下代码:

534行创建bean实例返回给BeanWrapper

563行addSingletonFactory增加beanNameObjectFactory的键值对应关系。
这里写图片描述
这里写图片描述

    /**     * Actually create the specified bean. Pre-creation processing has already happened     * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.     * <p>Differentiates between default bean instantiation, use of a     * factory method, and autowiring a constructor.     * @param beanName the name of the bean     * @param mbd the merged bean definition for the bean     * @param args explicit arguments to use for constructor or factory method invocation     * @return a new instance of the bean     * @throws BeanCreationException if the bean could not be created     * @see #instantiateBean     * @see #instantiateUsingFactoryMethod     * @see #autowireConstructor     */    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)            throws BeanCreationException {        // Instantiate the bean.        BeanWrapper instanceWrapper = null;        if (mbd.isSingleton()) {            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);        }        if (instanceWrapper == null) {            instanceWrapper = createBeanInstance(beanName, mbd, args);        }        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);        // Allow post-processors to modify the merged bean definition.        synchronized (mbd.postProcessingLock) {            if (!mbd.postProcessed) {                try {                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);                }                catch (Throwable ex) {                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,                            "Post-processing of merged bean definition failed", ex);                }                mbd.postProcessed = true;            }        }        // Eagerly cache singletons to be able to resolve circular references        // even when triggered by lifecycle interfaces like BeanFactoryAware.        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&                isSingletonCurrentlyInCreation(beanName));        if (earlySingletonExposure) {            if (logger.isDebugEnabled()) {                logger.debug("Eagerly caching bean '" + beanName +                        "' to allow for resolving potential circular references");            }            addSingletonFactory(beanName, new ObjectFactory<Object>() {                @Override                public Object getObject() throws BeansException {                    return getEarlyBeanReference(beanName, mbd, bean);                }            });        }

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

   /**     * Obtain a reference for early access to the specified bean,     * typically for the purpose of resolving a circular reference.     * @param beanName the name of the bean (for error handling purposes)     * @param mbd the merged bean definition for the bean     * @param bean the raw bean instance     * @return the object to expose as bean reference     */    protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {        Object exposedObject = bean;        if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {            for (BeanPostProcessor bp : getBeanPostProcessors()) {                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);                    if (exposedObject == null) {                        return null;                    }                }            }        }        return exposedObject;    }

原地址:http://www.cnblogs.com/chengxuyuanzhilu/p/6404991.html

0 0
原创粉丝点击