zoukankan      html  css  js  c++  java
  • 6.2-SingletonBeanRegistry-DefaultSingletonBeanRegistry

    SingletonBeanRegistry

    package org.springframework.beans.factory.config;
    
    
    public interface SingletonBeanRegistry {
    
        //在容器中创建一个指定的单利bean的类
        void registerSingleton(String beanName, Object singletonObject);
    
    //返回一个单利类
        Object getSingleton(String beanName);
    
        //判断容器红是否错在这个单例的bean
        boolean containsSingleton(String beanName);
    //返回这个单例bean的所有名字
        String[] getSingletonNames();
    
        //统计单例Bean的个数
        int getSingletonCount();
    
        
        Object getSingletonMutex();
    
    }

    DefaultSingletonBeanRegistry

    /*
     * Copyright 2002-2016 the original author or authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package org.springframework.beans.factory.support;
    
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.LinkedHashMap;
    import java.util.LinkedHashSet;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.ConcurrentHashMap;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    
    import org.springframework.beans.factory.BeanCreationException;
    import org.springframework.beans.factory.BeanCreationNotAllowedException;
    import org.springframework.beans.factory.BeanCurrentlyInCreationException;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.ObjectFactory;
    import org.springframework.beans.factory.config.SingletonBeanRegistry;
    import org.springframework.core.SimpleAliasRegistry;
    import org.springframework.util.Assert;
    import org.springframework.util.StringUtils;
    
    /**
     * Generic registry for shared bean instances, implementing the
     * {@link org.springframework.beans.factory.config.SingletonBeanRegistry}.
     * Allows for registering singleton instances that should be shared
     * for all callers of the registry, to be obtained via bean name.
     *
     * <p>Also supports registration of
     * {@link org.springframework.beans.factory.DisposableBean} instances,
     * (which might or might not correspond to registered singletons),
     * to be destroyed on shutdown of the registry. Dependencies between
     * beans can be registered to enforce an appropriate shutdown order.
     *
     * <p>This class mainly serves as base class for
     * {@link org.springframework.beans.factory.BeanFactory} implementations,
     * factoring out the common management of singleton bean instances. Note that
     * the {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
     * interface extends the {@link SingletonBeanRegistry} interface.
     *
     * <p>Note that this class assumes neither a bean definition concept
     * nor a specific creation process for bean instances, in contrast to
     * {@link AbstractBeanFactory} and {@link DefaultListableBeanFactory}
     * (which inherit from it). Can alternatively also be used as a nested
     * helper to delegate to.
     *
     * @author Juergen Hoeller
     * @since 2.0
     * @see #registerSingleton
     * @see #registerDisposableBean
     * @see org.springframework.beans.factory.DisposableBean
     * @see org.springframework.beans.factory.config.ConfigurableBeanFactory
     */
    public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    
        /**
         * Internal marker for a null singleton object:
         * used as marker value for concurrent Maps (which don't support null values).
         */
        protected static final Object NULL_OBJECT = new Object();
    
    
        /** Logger available to subclasses */
        protected final Log logger = LogFactory.getLog(getClass());
        
        // 缓存了bean的名称和bean的实例
        /** Cache of singleton objects: bean name --> bean instance */
        private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
        //缓存了bean的name 和  ObjectFactory
        /** Cache of singleton factories: bean name --> ObjectFactory */
        private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
        //缓存了已经存在单例,用于解决循环依赖的方法
        /** Cache of early singleton objects: bean name --> bean instance */
        private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
        //已经注册好的单例
        /** Set of registered singletons, containing the bean names in registration order */
        private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
        // 存正在初始化的bean。就不在发起初始化
        /** Names of beans that are currently in creation */
        private final Set<String> singletonsCurrentlyInCreation =
                Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
        // 直接缓存当前不能加载的bean
        /** Names of beans currently excluded from in creation checks */
        private final Set<String> inCreationCheckExclusions =
                Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
    
        /** List of suppressed Exceptions, available for associating related causes */
        private Set<Exception> suppressedExceptions;
    
        /** Flag that indicates whether we're currently within destroySingletons */
        private boolean singletonsCurrentlyInDestruction = false;
        //
        /** Disposable bean instances: bean name --> disposable instance */
        private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
    
        /** Map between containing bean names: bean name --> Set of bean names that the bean contains */
        private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);
        //查找依赖的类
        /** Map between dependent bean names: bean name --> Set of dependent bean names */
        private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
         //被依赖的bean name为key
        /** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
        private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
    
    
        //注册单例bean 
        @Override
        public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
            Assert.notNull(beanName, "'beanName' must not be null");
            synchronized (this.singletonObjects) {
                Object oldObject = this.singletonObjects.get(beanName);
                if (oldObject != null) {
                    throw new IllegalStateException("Could not register object [" + singletonObject +
                            "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
                }
                addSingleton(beanName, singletonObject);
            }
        }
    
        /**
         * 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);
            }
        }
    
        /**
         * Add the given singleton factory for building the specified singleton
         * if necessary.
         * <p>To be called for eager registration of singletons, e.g. to be able to
         * resolve circular references.
         * @param beanName the name of the bean
         * @param singletonFactory the factory for the singleton object
         */
        protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(singletonFactory, "Singleton factory must not be null");
            synchronized (this.singletonObjects) {
                if (!this.singletonObjects.containsKey(beanName)) {
                    this.singletonFactories.put(beanName, singletonFactory);
                    this.earlySingletonObjects.remove(beanName);
                    this.registeredSingletons.add(beanName);
                }
            }
        }
    
        @Override
        public Object getSingleton(String beanName) {
            return getSingleton(beanName, true);
        }
    
        /**
         * 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);
        }
    
        /**
         * Return the (raw) singleton object registered under the given name,
         * creating and registering a new one if none registered yet.
         * @param beanName the name of the bean
         * @param singletonFactory the ObjectFactory to lazily create the singleton
         * with, if necessary
         * @return the registered singleton object
         */
        public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(beanName, "'beanName' must not be null");
            synchronized (this.singletonObjects) {
                Object singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    if (this.singletonsCurrentlyInDestruction) {
                        throw new BeanCreationNotAllowedException(beanName,
                                "Singleton bean creation not allowed while the singletons of this factory are in destruction " +
                                "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                    }
                    if (logger.isDebugEnabled()) {
                        logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                    }
                    beforeSingletonCreation(beanName);
                    boolean newSingleton = false;
                    boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = new LinkedHashSet<Exception>();
                    }
                    try {
                        singletonObject = singletonFactory.getObject();
                        newSingleton = true;
                    }
                    catch (IllegalStateException ex) {
                        // Has the singleton object implicitly appeared in the meantime ->
                        // if yes, proceed with it since the exception indicates that state.
                        singletonObject = this.singletonObjects.get(beanName);
                        if (singletonObject == null) {
                            throw ex;
                        }
                    }
                    catch (BeanCreationException ex) {
                        if (recordSuppressedExceptions) {
                            for (Exception suppressedException : this.suppressedExceptions) {
                                ex.addRelatedCause(suppressedException);
                            }
                        }
                        throw ex;
                    }
                    finally {
                        if (recordSuppressedExceptions) {
                            this.suppressedExceptions = null;
                        }
                        afterSingletonCreation(beanName);
                    }
                    if (newSingleton) {
                        addSingleton(beanName, singletonObject);
                    }
                }
                return (singletonObject != NULL_OBJECT ? singletonObject : null);
            }
        }
    
        /**
         * Register an Exception that happened to get suppressed during the creation of a
         * singleton bean instance, e.g. a temporary circular reference resolution problem.
         * @param ex the Exception to register
         */
        protected void onSuppressedException(Exception ex) {
            synchronized (this.singletonObjects) {
                if (this.suppressedExceptions != null) {
                    this.suppressedExceptions.add(ex);
                }
            }
        }
    
        /**
         * Remove the bean with the given name from the singleton cache of this factory,
         * to be able to clean up eager registration of a singleton if creation failed.
         * @param beanName the name of the bean
         * @see #getSingletonMutex()
         */
        protected void removeSingleton(String beanName) {
            synchronized (this.singletonObjects) {
                this.singletonObjects.remove(beanName);
                this.singletonFactories.remove(beanName);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.remove(beanName);
            }
        }
    
        @Override
        public boolean containsSingleton(String beanName) {
            return this.singletonObjects.containsKey(beanName);
        }
    
        @Override
        public String[] getSingletonNames() {
            synchronized (this.singletonObjects) {
                return StringUtils.toStringArray(this.registeredSingletons);
            }
        }
    
        @Override
        public int getSingletonCount() {
            synchronized (this.singletonObjects) {
                return this.registeredSingletons.size();
            }
        }
    
    
        public void setCurrentlyInCreation(String beanName, boolean inCreation) {
            Assert.notNull(beanName, "Bean name must not be null");
            if (!inCreation) {
                this.inCreationCheckExclusions.add(beanName);
            }
            else {
                this.inCreationCheckExclusions.remove(beanName);
            }
        }
    
        public boolean isCurrentlyInCreation(String beanName) {
            Assert.notNull(beanName, "Bean name must not be null");
            return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
        }
    
        protected boolean isActuallyInCreation(String beanName) {
            return isSingletonCurrentlyInCreation(beanName);
        }
    
        /**
         * Return whether the specified singleton bean is currently in creation
         * (within the entire factory).
         * @param beanName the name of the bean
         */
        public boolean isSingletonCurrentlyInCreation(String beanName) {
            return this.singletonsCurrentlyInCreation.contains(beanName);
        }
    
        /**
         * Callback before singleton creation.
         * <p>The default implementation register the singleton as currently in creation.
         * @param beanName the name of the singleton about to be created
         * @see #isSingletonCurrentlyInCreation
         */
        protected void beforeSingletonCreation(String beanName) {
            if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
        }
    
        /**
         * Callback after singleton creation.
         * <p>The default implementation marks the singleton as not in creation anymore.
         * @param beanName the name of the singleton that has been created
         * @see #isSingletonCurrentlyInCreation
         */
        protected void afterSingletonCreation(String beanName) {
            if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
                throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
            }
        }
    
    
        /**
         * Add the given bean to the list of disposable beans in this registry.
         * <p>Disposable beans usually correspond to registered singletons,
         * matching the bean name but potentially being a different instance
         * (for example, a DisposableBean adapter for a singleton that does not
         * naturally implement Spring's DisposableBean interface).
         * @param beanName the name of the bean
         * @param bean the bean instance
         */
        public void registerDisposableBean(String beanName, DisposableBean bean) {
            synchronized (this.disposableBeans) {
                this.disposableBeans.put(beanName, bean);
            }
        }
    
        /**
         * Register a containment relationship between two beans,
         * e.g. between an inner bean and its containing outer bean.
         * <p>Also registers the containing bean as dependent on the contained bean
         * in terms of destruction order.
         * @param containedBeanName the name of the contained (inner) bean
         * @param containingBeanName the name of the containing (outer) bean
         * @see #registerDependentBean
         */
        public void registerContainedBean(String containedBeanName, String containingBeanName) {
            // A quick check for an existing entry upfront, avoiding synchronization...
            Set<String> containedBeans = this.containedBeanMap.get(containingBeanName);
            if (containedBeans != null && containedBeans.contains(containedBeanName)) {
                return;
            }
    
            // No entry yet -> fully synchronized manipulation of the containedBeans Set
            synchronized (this.containedBeanMap) {
                containedBeans = this.containedBeanMap.get(containingBeanName);
                if (containedBeans == null) {
                    containedBeans = new LinkedHashSet<String>(8);
                    this.containedBeanMap.put(containingBeanName, containedBeans);
                }
                containedBeans.add(containedBeanName);
            }
            registerDependentBean(containedBeanName, containingBeanName);
        }
    
        /**
         * Register a dependent bean for the given bean,
         * to be destroyed before the given bean is destroyed.
         * @param beanName the name of the bean
         * @param dependentBeanName the name of the dependent bean
         */
        public void registerDependentBean(String beanName, String dependentBeanName) {
            // A quick check for an existing entry upfront, avoiding synchronization...
            String canonicalName = canonicalName(beanName);
            Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
            if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
                return;
            }
    
            // No entry yet -> fully synchronized manipulation of the dependentBeans Set
            synchronized (this.dependentBeanMap) {
                dependentBeans = this.dependentBeanMap.get(canonicalName);
                if (dependentBeans == null) {
                    dependentBeans = new LinkedHashSet<String>(8);
                    this.dependentBeanMap.put(canonicalName, dependentBeans);
                }
                dependentBeans.add(dependentBeanName);
            }
            synchronized (this.dependenciesForBeanMap) {
                Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
                if (dependenciesForBean == null) {
                    dependenciesForBean = new LinkedHashSet<String>(8);
                    this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
                }
                dependenciesForBean.add(canonicalName);
            }
        }
    
        /**
         * Determine whether the specified dependent bean has been registered as
         * dependent on the given bean or on any of its transitive dependencies.
         * @param beanName the name of the bean to check
         * @param dependentBeanName the name of the dependent bean
         * @since 4.0
         */
        protected boolean isDependent(String beanName, String dependentBeanName) {
            return isDependent(beanName, dependentBeanName, null);
        }
    
        private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
            if (alreadySeen != null && alreadySeen.contains(beanName)) {
                return false;
            }
            String canonicalName = canonicalName(beanName);
            Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
            if (dependentBeans == null) {
                return false;
            }
            if (dependentBeans.contains(dependentBeanName)) {
                return true;
            }
            for (String transitiveDependency : dependentBeans) {
                if (alreadySeen == null) {
                    alreadySeen = new HashSet<String>();
                }
                alreadySeen.add(beanName);
                if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
                    return true;
                }
            }
            return false;
        }
    
        /**
         * Determine whether a dependent bean has been registered for the given name.
         * @param beanName the name of the bean to check
         */
        protected boolean hasDependentBean(String beanName) {
            return this.dependentBeanMap.containsKey(beanName);
        }
    
        /**
         * Return the names of all beans which depend on the specified bean, if any.
         * @param beanName the name of the bean
         * @return the array of dependent bean names, or an empty array if none
         */
        public String[] getDependentBeans(String beanName) {
            Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
            if (dependentBeans == null) {
                return new String[0];
            }
            return StringUtils.toStringArray(dependentBeans);
        }
    
        /**
         * Return the names of all beans that the specified bean depends on, if any.
         * @param beanName the name of the bean
         * @return the array of names of beans which the bean depends on,
         * or an empty array if none
         */
        public String[] getDependenciesForBean(String beanName) {
            Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);
            if (dependenciesForBean == null) {
                return new String[0];
            }
            return dependenciesForBean.toArray(new String[dependenciesForBean.size()]);
        }
    
        public void destroySingletons() {
            if (logger.isDebugEnabled()) {
                logger.debug("Destroying singletons in " + this);
            }
            synchronized (this.singletonObjects) {
                this.singletonsCurrentlyInDestruction = true;
            }
    
            String[] disposableBeanNames;
            synchronized (this.disposableBeans) {
                disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
            }
            for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
                destroySingleton(disposableBeanNames[i]);
            }
    
            this.containedBeanMap.clear();
            this.dependentBeanMap.clear();
            this.dependenciesForBeanMap.clear();
    
            synchronized (this.singletonObjects) {
                this.singletonObjects.clear();
                this.singletonFactories.clear();
                this.earlySingletonObjects.clear();
                this.registeredSingletons.clear();
                this.singletonsCurrentlyInDestruction = false;
            }
        }
    
        /**
         * Destroy the given bean. Delegates to {@code destroyBean}
         * if a corresponding disposable bean instance is found.
         * @param beanName the name of the bean
         * @see #destroyBean
         */
        public void destroySingleton(String beanName) {
            // Remove a registered singleton of the given name, if any.
            removeSingleton(beanName);
    
            // Destroy the corresponding DisposableBean instance.
            DisposableBean disposableBean;
            synchronized (this.disposableBeans) {
                disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
            }
            destroyBean(beanName, disposableBean);
        }
    
        /**
         * Destroy the given bean. Must destroy beans that depend on the given
         * bean before the bean itself. Should not throw any exceptions.
         * @param beanName the name of the bean
         * @param bean the bean instance to destroy
         */
        protected void destroyBean(String beanName, DisposableBean bean) {
            // Trigger destruction of dependent beans first...
            Set<String> dependencies = this.dependentBeanMap.remove(beanName);
            if (dependencies != null) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
                }
                for (String dependentBeanName : dependencies) {
                    destroySingleton(dependentBeanName);
                }
            }
    
            // Actually destroy the bean now...
            if (bean != null) {
                try {
                    bean.destroy();
                }
                catch (Throwable ex) {
                    logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
                }
            }
    
            // Trigger destruction of contained beans...
            Set<String> containedBeans = this.containedBeanMap.remove(beanName);
            if (containedBeans != null) {
                for (String containedBeanName : containedBeans) {
                    destroySingleton(containedBeanName);
                }
            }
    
            // Remove destroyed bean from other beans' dependencies.
            synchronized (this.dependentBeanMap) {
                for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
                    Map.Entry<String, Set<String>> entry = it.next();
                    Set<String> dependenciesToClean = entry.getValue();
                    dependenciesToClean.remove(beanName);
                    if (dependenciesToClean.isEmpty()) {
                        it.remove();
                    }
                }
            }
    
            // Remove destroyed bean's prepared dependency information.
            this.dependenciesForBeanMap.remove(beanName);
        }
    
        /**
         * Exposes the singleton mutex to subclasses and external collaborators.
         * <p>Subclasses should synchronize on the given Object if they perform
         * any sort of extended singleton creation phase. In particular, subclasses
         * should <i>not</i> have their own mutexes involved in singleton creation,
         * to avoid the potential for deadlocks in lazy-init situations.
         */
        public final Object getSingletonMutex() {
            return this.singletonObjects;
        }
    
    }

    注册bean的这段代码:

        @Override
        public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
            Assert.notNull(beanName, "'beanName' must not be null");
            synchronized (this.singletonObjects) {
                Object oldObject = this.singletonObjects.get(beanName);
                if (oldObject != null) {
                    throw new IllegalStateException("Could not register object [" + singletonObject +
                            "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
                }
                addSingleton(beanName, singletonObject);
            }
        }

    同样使用了同步方法来维护线程的安全, 调用了

     addSingleton(beanName, singletonObject);

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

    上述的方法中我们可以看出,存储bean的几个集合的关系了,

    singletonObjects,
    registeredSingletons是同步的,和
    singletonFactories
    earlySingletonObjects是相互对立的关系,不会同时存在



    管理bean的依赖问题

    
    

      使用如下三个属性进行管理:

    
    

      Map<String, Set<String>> containedBeanMap  依赖的bean name为key , 就是依赖类 -> 查找 被依赖的类

    
    

      Map<String, Set<String>> dependentBeanMap  依赖的原始bean name为key

    
    

      Map<String, Set<String>> dependenciesForBeanMap  被依赖的bean name为key

    在进行public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) 时候,先进行了

    beforeSingletonCreation这边inCreationCheckExclusions不包含beanName才会去判断singletonsCurrentlyInCreation
        protected void beforeSingletonCreation(String beanName) {
            if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
        }

    销毁:最后还有一个public void destroySingleton(String beanName)的方法,

    其实源码中就是把之前存在集合中得Bean进行了移除!就相当于是销毁了。







    解释不合理的地方,请指正!谢谢了!
     

     
  • 相关阅读:
    传输速率转换
    CentOS7 安装 oracleXE(快捷版)教程
    QEMU/KVM虚拟机安装配置
    Nginx 1.10.1 编译、配置文档(支持http_v2,TLSv1.2,openssl v1.0.2)
    IDC机房线路质量测试方案
    Iptables防火墙NAT地址转换与端口转发
    Zabbix使用点滴
    MySQL基本命令
    防DDOS攻击SHELL脚本
    12月份的英文简写
  • 原文地址:https://www.cnblogs.com/java-synchronized/p/6795756.html
Copyright © 2011-2022 走看看