Spring之DefaultListableBeanFactory

1、DefaultListableBeanFactory介绍

大家都知道Spring的核心功能有IOC,那么IOC的核心是什么呢?其实就是DefaultListableBeanFactory,BeanFactory是初学者都知道的Spring基本实现思想,但是BeanFactory只是个借口,归根结底需要类去实现的,而DefaultListableBeanFactory就是真正实现了容器接口并可以独立使用的类,所以谈及IOC,必须要对DefaultListableBeanFactory有所了解。老方式,先看顶层接口,一步一步来!
DefaultListableBeanFactory继承关系

1.1、AliasRegistry 接口

AliasRegistry接口从名字中很容易理解,就是为bean注册别名用的,方法也很简单,定义了对alias的简单的简单增改删等操作。
AliasRegistry 接口能力

1.2、BeanDefinitionRegistry 接口

BeanDefinitionRegistry 继承结构

BeanDefinitionRegistry接口定义对BeanDefinition的各种增改删查操作。BeanDefinition中定义的属性有诸如类名、sccope、属性、构造函数参数列表、依赖的bean、是否单例类、是否懒加载等,其实就是将Bean的定义信息存储到这个BeanDefinition相应的属性中,之后对Bean的操作就是直接对BeanDefinition进行的,说白了就是描述bean的,就像汽车的图纸一样,有了它,就可以创建出该规格的bean。

1.3、SimpleAliasRegistry 类

SimpleAliasRegistry 类机构

这个类不复杂,仅仅实现了AliasRegistry接口,实现原理也很简单,是通过把bean的别名放在一个Map中实现的,后续对别名的操作都是在操作这个Map,Spring的一贯实现方式。

1.4、SingletonBeanRegistry 接口

SingletonBeanRegistry 继承结构
看接口能力很简单,就是对单例共享bean进行注册用的,注意别跟上面的BeanDefinitionRegistry搞混了,BeanDefinitionRegistry是注册bean定义的,而SingletonBeanRegistry是中注册单例bean对象的,二者其实差别很大的哦。看二者的核心注册方法就明白啦。一个是registerBeanDefinition(String, BeanDefinition),一个是registerSingleton(String, Object),慢慢品品。

1.5、DefaultSingletonBeanRegistry 类

DefaultSingletonBeanRegistry 继承结构

终于来了重要的类了,Spring的bean其实都是在这个类中被管理,其中老生常谈的二级缓存、三级缓存什么的其实就是一个个不同功能的Map。主要有如下功能:

  • 存储单例Bean
  • 存储Bean之间的依赖关系
  • 存储Bean的包含关系(外部类包含内部类)
  • Bean所处的状态(正在创建、创建完毕等)
  • 负责单例Bean的销毁(在其中会看到销毁方法的回调)
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    /** Cache of singleton objects: bean name to bean instance. */
    // 缓存完全实例化的Bean
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    /** Cache of singleton factories: bean name to ObjectFactory. */
    //单例工厂的缓存:从bean名到ObjectFactory。解决循环依赖,用来存放未完全实例化的Bean
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    /** Cache of early singleton objects: bean name to bean instance. */
    //早期单例对象的缓存:还没有填充属性,存放具有setter循环依赖的未完全实例化的Bean
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    /** Set of registered singletons, containing the bean names in registration order. */
    //存放已经实例化的bean的名称,LinkedHashSet可以看出beanName是按注册顺序的先后存放的
    private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

    /** Names of beans that are currently in creation. */
    // 目前正在创建的Bean的名称(构造函数依赖于其他未初始化的Bean)
    private final Set<String> singletonsCurrentlyInCreation =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    /** Names of beans currently excluded from in creation checks.*/
    // 可以免除创建状态(即是否检查有无完全初始化)检查的bean的名称,大概是用于存储非单例Bean的名字,inCreationCheckExclusions存在的beanName,可以并发创建。
    private final Set<String> inCreationCheckExclusions =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    /** List of suppressed Exceptions, available for associating related causes. */
    // 当从ObjectFactory获得对象时出现异常,把suppressedExceptions的异常一并抛出。作用不大
    @Nullable
    private Set<Exception> suppressedExceptions;

    /** Flag that indicates whether we're currently within destroySingletons. */
    // 当前是否处于销毁Bean的状态,若为true,则无法获得Bean
    private boolean singletonsCurrentlyInDestruction = false;

    /** Disposable bean instances: bean name to disposable instance. */
    // 所有实现了DisposableBean接口的Bean,在销毁Bean时,会回调该缓存中Bean的destroy方法
    private final Map<String, Object> disposableBeans = new LinkedHashMap<>();

    /** Map between containing bean names: bean name to Set of bean names that the bean contains. */
    // 缓存所有外部类与内部类的关系
    private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);

    /** Map between dependent bean names: bean name to Set of dependent bean names. */
    // 存放bean名称和所有依赖于该Bean的bean名称集合
    private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

    /** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
    // bean名称和该bean所依赖的所有bean名称的集合
    private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
}

看看这么多属性是不是头皮发麻?慢慢分析吧!

1.5.1、登记完全实例化的Bean
   @Override
    public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
        Assert.notNull(beanName, "Bean name must not be null");
        Assert.notNull(singletonObject, "Singleton object must not be null");
        synchronized (this.singletonObjects) {
            //确保Bean已经完全初始化(实例化+注入全部依赖)
            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) {
            //移除singletonFactories、earlySingletonObjects中对应的bean
            //singletonFactories、earlySingletonObjects、singletonObjects三个缓存具有一定缓存意义
            //在之前的属性介绍中已经说明
            this.singletonObjects.put(beanName, singletonObject);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            //登记已经完成初始化的Bean
            this.registeredSingletons.add(beanName);
        }
    }
1.5.2、添加Bean到singletonFactories
    /**
     * 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
     */
     
     //将未完全实例化的Bean(有些依赖未注入)封装成ObjectFactory类型后
     //存储到singletonFactories缓存中
     //目的:为了解决setter循环依赖(接下来会解析)
    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized (this.singletonObjects) {
            //确保bean未完全初始化
            if (!this.singletonObjects.containsKey(beanName)) {
                this.singletonFactories.put(beanName, singletonFactory);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }
        }
    }
1.5.3、获取Bean
    @Override
    @Nullable
    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
     */
    @Nullable
    /*
    *这个函数一般用于获得依赖Bean或是完全初始化的Bean,按以下顺序进行获取
    *1、从singletonObjects缓存中获取,意味着依赖Bean已经完全初始化(实例化+注入全部依赖)
    *2、从earlySingletonObjects缓存中获取,意味着依赖Bean出现了setter循环依赖,这里获得的是引用
    *3、从singletonFactories缓存中获取,意味着依赖Bean也还没有完全初始化,这里获得的是引用
    */
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        //isSingletonCurrentlyInCreation函数用于确保Bean正在创建
        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;
    }
 
    /**
     * Return whether the specified singleton bean is currently in creation
     * (within the entire factory).
     * @param beanName the name of the bean
     */
     //当前是否处于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
     * 判断Bean是否处于初始化阶段,如果Bean已经处于初始化阶段,则抛出异常,这个函数用于确保单例唯一,否则返回
     */  
    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
     * 表明单例Bean初始化完毕
     */
    protected void afterSingletonCreation(String beanName) {
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
            throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
        }
    }
    
    /**
     * 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
     * 这个函数直接从ObjectFactory获得Bean,直接存储到singletonObjects缓存中,用于创建单例Bean
     */
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                //当前是否处于Bean销毁状态,若处于,则抛出异常,此时不能获得Bean
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while 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 + "'");
                }
                
                //判断Bean是否处于初始化阶段,确保单例唯一
                beforeSingletonCreation(beanName);
                
                
                boolean newSingleton = false;
                
                //从ObjectFactory获取对象失败时需要一并抛出的异常
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    //从ObjectFactory中获取对象
                    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;
                    }
                    //实例化完毕单例Bean
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    //添加到singletonObjects缓存中
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }
1.5.4、getter与setter函数
    //获得单例bean的名称列表
    @Override
    public String[] getSingletonNames() {
        synchronized (this.singletonObjects) {
            return StringUtils.toStringArray(this.registeredSingletons);
        }
    }
 
    //获得singletonMutex,调用这个函数的地方必须上锁
    public final Object getSingletonMutex() {
        return this.singletonObjects;
    }
 
    //获得单例bean的个数
    @Override
    public int getSingletonCount() {
        synchronized (this.singletonObjects) {
            return this.registeredSingletons.size();
        }
    }
 
    //存储可以并发创建的bean的名称
    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);
        }
    }
 
     /**
     * 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
     *返回依赖于该Bean的Bean的名字
     */
    public String[] getDependentBeans(String beanName) {
        Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
        if (dependentBeans == null) {
            return new String[0];
        }
        synchronized (this.dependentBeanMap) {
            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
     * 返回该Bean的依赖
     */
    public String[] getDependenciesForBean(String beanName) {
        Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);
        if (dependenciesForBean == null) {
            return new String[0];
        }
        synchronized (this.dependenciesForBeanMap) {
            return StringUtils.toStringArray(dependenciesForBean);
        }
    }
1.5.5、用于判断的函数
    //这三个函数用于判断单例Bean是否正在被创建
    //返回false有两种可能
    //1、beanName不是单例bean
    //2、单例bean未处于创建状态
    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);
    }
    /**
     * 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
     * 这两个函数用于判断dependentBeanName是否直接或是间接依赖于beanName
     * bean与bean之间的依赖关系可以构成一张图或是一棵树,这里采用深度优先算法遍历beanName的依赖树(图),这个方法在初始化时,会检查依据depends-on属性形成的依赖图中是否有循环依赖
     */
    protected boolean isDependent(String beanName, String dependentBeanName) {
        synchronized (this.dependentBeanMap) {
            return isDependent(beanName, dependentBeanName, null);
        }
    }
 
    private boolean isDependent(String beanName, String dependentBeanName, @Nullable 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<>();
            }
            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
     * 判断是否有bean依赖于beanName对应的bean
     */
    protected boolean hasDependentBean(String beanName) {
        return this.dependentBeanMap.containsKey(beanName);
    }
1.5.6、记录bean与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
     * 记录具有包含关系的bean(内部类与外部类)
     */
    public void registerContainedBean(String containedBeanName, String containingBeanName) {
        synchronized (this.containedBeanMap) {
            Set<String> containedBeans =
                    this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8));
            if (!containedBeans.add(containedBeanName)) {
                return;
            }
        }
        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
     * 记录dependentBeanName依赖于beanName,分为两步,第一步将dependentBeanName加入到依赖于
     *beanName的bean的记录项中,第二步将beanName加入到dependentBeanName的依赖记录项中
     */
    public void registerDependentBean(String beanName, String dependentBeanName) {
        String canonicalName = canonicalName(beanName);
 
        synchronized (this.dependentBeanMap) {
            Set<String> dependentBeans =
                    this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
            if (!dependentBeans.add(dependentBeanName)) {
                return;
            }
        }
 
        synchronized (this.dependenciesForBeanMap) {
            Set<String> dependenciesForBean =
                    this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
            dependenciesForBean.add(canonicalName);
        }
    }
1.5.7、注册实现了DisposableBean接口的类
    /**
     * 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);
        }
    }
1.5.8、销毁Bean的函数
    //删除所有的单例Bean
    public void destroySingletons() {
        if (logger.isTraceEnabled()) {
            logger.trace("Destroying singletons in " + this);
        }
        //设置标志,表明现在正在销毁单例bean,不允许获得单例bean
        synchronized (this.singletonObjects) {
            this.singletonsCurrentlyInDestruction = true;
        }
 
        String[] disposableBeanNames;
        synchronized (this.disposableBeans) {
            disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
        }
        //首先调用实现了DisposableBean的bean的destroy()方法
        for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
            destroySingleton(disposableBeanNames[i]);
        }
 
        //清除所有存储bean之间关系的缓存
        this.containedBeanMap.clear();
        this.dependentBeanMap.clear();
        this.dependenciesForBeanMap.clear();
 
        clearSingletonCache();
    }
 
    /**
     * Clear all cached singleton instances in this registry.
     * @since 4.3.15
     * 清楚所有的bean缓存
     */
    protected void clearSingletonCache() {
        synchronized (this.singletonObjects) {
            this.singletonObjects.clear();
            this.singletonFactories.clear();
            this.earlySingletonObjects.clear();
            this.registeredSingletons.clear();
            this.singletonsCurrentlyInDestruction = false;
        }
    }
 
    /**
     * 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()
     * 移除特定的Bean的缓存
     */
    protected void removeSingleton(String beanName) {
        synchronized (this.singletonObjects) {
            this.singletonObjects.remove(beanName);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.remove(beanName);
        }
    }
    
    /**
     * 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
     * 删除特定的单例Bean
     */
    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
     * 依据深度优先删除beanName以及依赖于beanName的bean,最终会把一个依赖图谱给删除
     */
    protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
        // Trigger destruction of dependent beans first...
        Set<String> dependencies;
        synchronized (this.dependentBeanMap) {
            // Within full synchronization in order to guarantee a disconnected Set
            //清除记录依赖于beanName的bean的缓存
            dependencies = this.dependentBeanMap.remove(beanName);
        }
        if (dependencies != null) {
            if (logger.isTraceEnabled()) {
                logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
            }
            //依次删除依赖于beanName的bean
            for (String dependentBeanName : dependencies) {
                destroySingleton(dependentBeanName);
            }
        }
 
        // Actually destroy the bean now...
        if (bean != null) {
            try {
                //调用销毁回调
                bean.destroy();
            }
            catch (Throwable ex) {
                if (logger.isInfoEnabled()) {
                    logger.info("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
                }
            }
        }
 
        // Trigger destruction of contained beans...
        // 销毁包含关系的bean,由此可以确定,A依赖于B(A、B均实现了DisposableBean接口),则A的destroy方法比B的先调用
        Set<String> containedBeans;
        synchronized (this.containedBeanMap) {
            // Within full synchronization in order to guarantee a disconnected Set
            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.
        //清除记录beanName的依赖关系的缓存
        this.dependenciesForBeanMap.remove(beanName);
    }

1.6、如何解决setter循环依赖

Bean的创建会经过三个过程:

  • createBeanInstance:调用对象的构造方法实例化对象
  • populateBean:填充属性,包括依赖注入
  • initializeBean:调用init 方法
    假设有两个Bean,A与B,A与B相互通过setter函数依赖,A先通过createBeanInstance函数初始化,A是不完全的,某些依赖(B)还没有注入,会调用DefaultSingletonBeanRegistry的addSingletonFactory函数:
addSingletonFactory(beanName, new ObjectFactory<Object>() {
   @Override   public Object getObject() throws BeansException {
      return getEarlyBeanReference(beanName, mbd, bean);
   }});

A被封装成ObjectFactory,保存进singletonFactories中,A发现自己依赖于B,调用DefaultSingletonBeanRegistry的getSingleton(String beanName)函数,该函数返回值为null,A发现B还没有初始化,此时会使用createBeanInstance函数初始化B,B发现自己依赖于A,调用DefaultSingletonBeanRegistry的getSingleton(String beanName)函数,这里方便讲解,我在拷贝一遍函数:

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

这个函数首先会查找singletonObjects缓存(没有查找到A),接着查找earlySingletonObjects(没有查找到A),接着会查找singletonFactories,此时会查找到之前封装了A的ObjectFactory,调用其getObject方法,获得A,接着将A放入earlySingletonObjects,此时B获得A实例,完成初始化,调用DefaultSingletonBeanRegistry的addSingleton(String beanName, Object singletonObject)方法,将自己放入singletonObjects缓存中,B初始化完成后,A也能完成初始化,调用addSingleton(String beanName, Object singletonObject)方法,从earlySingletonObjects缓存进入singletonObjects缓存,由于A可以率先初始化,所以上述过程可以完成,如果A的构造函数依赖于B,B的构造函数又依赖于A,这样两者都无法率先初始化,两者都无法率先进入singletonFactories缓存。
如果A又与C出现setter循环依赖,C在调用DefaultSingletonBeanRegistry的getSingleton(String beanName, boolean allowEarlyReference) 方法时,会从earlySingletonObjects中获得A。
这里总结一下三个缓存的作用:

  • singletonObjects:存储完全实例化的Bean
  • earlySingletonObjects:存储具有循环依赖的Bean
  • singletonFactories:存储未完全实例化完毕的Bean(某些依赖未注入)

1.7、FactoryBeanRegistrySupport 抽象类
FactoryBeanRegistrySupport 类继承结构

FactoryBeanRegistrySupport主要是在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能,下面我们来看下具体的源码:

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
 
    //缓存factoryBeans创建的singletong对象
    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);
 
 
    //获取指定factoryBean中实例化对象的类型
    protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) {
        try {
            //此处是JDK的权限控制,主要是操作系统层面的权限
            //我们开发中很少用到
            if (System.getSecurityManager() != null) {
                return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
                    @Override
                    public Class<?> run() {
                        return factoryBean.getObjectType();
                    }
                }, getAccessControlContext());
            }
            else {
                return factoryBean.getObjectType();
            }
        }
        catch (Throwable ex) {
            return null;
        }
    }
 
    //从缓存中获取指定的beanName的对象如果是NULL_OBJECT则返回null
    protected Object getCachedObjectForFactoryBean(String beanName) {
        Object object = this.factoryBeanObjectCache.get(beanName);
        return (object != NULL_OBJECT ? object : null);
    }
 
    //从指定的FactoryBean中获得给定beanName的实例对象
    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
           //判断工厂是否是单例,以及单例缓存中是否有beanName
        if (factory.isSingleton() && containsSingleton(beanName)) {
            //单例缓存加上同步快防止并发
            synchronized (getSingletonMutex()) {
                //判断factoryBean中是否有指定的beanName
                Object object = this.factoryBeanObjectCache.get(beanName);
                if (object == null) {
                    //如果缓存中没有,通过factoryBean获取对象
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    //再次从缓存中获取对象
                    //如果存在则赋值给object对象
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    //不存在的话则获取,并存放到缓存池中
                    else {
                        if (object != null && shouldPostProcess) {
                            try {
                                //此获取对象的方法一般有子类实现
                                object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of FactoryBean's singleton object failed", ex);
                            }
                        }
                           //将对象存放到缓存中
                        this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
                    }
                }
                //返回对象,如果是空对象的话则返回null
                return (object != NULL_OBJECT ? object : null);
            }
        }
        else {
            //通过factoryBean获取对象
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            if (object != null && shouldPostProcess) {
                try {
                     //此获取对象的方法一般有子类实现
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                }
            }
            //返回对象
            return object;
        }
    }
 
    //通过factoryBean获取对象
    private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
            throws BeanCreationException {
 
        Object object;
        try {
               //此处是JDK的权限控制,主要是操作系统层面的权限
            //我们开发中很少用到
            if (System.getSecurityManager() != null) {
                AccessControlContext acc = getAccessControlContext();
                try {
                    object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                        @Override
                        public Object run() throws Exception {
                                return factory.getObject();
                            }
                        }, acc);
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                //factoryBean直接获取对象,上一篇我们可以看到具体入口,怎么一步步进来
                object = factory.getObject();
            }
        }
        catch (FactoryBeanNotInitializedException ex) {
            throw new BeanCurrentlyInCreationException(beanName, ex.toString());
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
        }
 
        // 不允许对象为空,或者正在创建
        if (object == null && isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(
                    beanName, "FactoryBean which is currently in creation returned null from getObject");
        }
        return object;
    }
 
    //此方法一般由子类重写
    protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
        return object;
    }
 
    //获取指定名称的factoryBean,如果该实例是factoryBean的话,否则报错
    protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException {
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanCreationException(beanName,
                    "Bean instance of type [" + beanInstance.getClass() + "] is not a FactoryBean");
        }
        return (FactoryBean<?>) beanInstance;
    }
 
    //移除指定的单例对象
    @Override
    protected void removeSingleton(String beanName) {
        super.removeSingleton(beanName);
        this.factoryBeanObjectCache.remove(beanName);
    }
 
    //权限管理,系统层面
    protected AccessControlContext getAccessControlContext() {
        return AccessController.getContext();
    }
 
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容