本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
Spring BeanFactory工厂使用教程
mycodes · 114浏览 · 发布于2023-02-07 +关注

Spring的本质是一个bean工厂(beanFactory)或者说bean容器,它按照我们的要求,生产我们需要的各种各样的bean,提供给我们使用。只是在生产bean的过程中,需要解决bean之间的依赖问题,才引入了依赖注入(DI)这种技术

首先,我们想要知道一个接口有哪些功能,就必须要看这个接口的源代码,在idea中,选中这个接口Ctrl+F12,来查看这个接口里面有哪些方法:

表面上来看,功能其实很少,查看源码及其方法、功能

package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
public interface BeanFactory {
    // factoryBean 的转义标识符。
    String FACTORY_BEAN_PREFIX = "&";
    // 根据 name 从容器中拿对应的 bean。
    Object getBean(String name) throws BeansException;
    // 根据 name 和 type 从容器中拿对应的 bean,要对 bean 的类型做校验。
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    // 在容器中能否找到与 name 匹配的 bean 或者 beanDefinition。
    boolean containsBean(String name);
    // 判断 name 对对应的 bean 是不是 单例。
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    // 判断 name 对应的 bean 与指定的类型是否匹配。
    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws
     NoSuchBeanDefinitionException;
    boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws
       NoSuchBeanDefinitionException;
    //根据 name 获取对应的 bean 的类型。
    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    // 根据 name 获取对应 bean 的 别名。
    String[] getAliases(String name);
}

BeanFactory表面上来看只有 getBean有点用,实际上我们不能只光看它接口,还要看它的实现类,实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供

  • HierarchicalBeanFactory:提供父容器的访问功能

  • ListableBeanFactory:提供了批量获取Bean的方法

  • AutowireCapableBeanFactory:在BeanFactory基础上实现对已存在实例的管理

  • ConfigurableBeanFactory:主要单例bean的注册,生成实例,以及统计单例bean

  • ConfigurableListableBeanFactory:继承了上述的所有接口,增加了其他功能:比如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系, bean如何销毁…

  • 实现类DefaultListableBeanFactory:实现了ConfigurableListableBeanFactory,注册BeanDefinition,实现上述BeanFactory所有功能

来看一下DefaultListableBeanFactory的继承关系图:

可以看到,BeanFactory只是它实现的很少一部分,除了BeanFactory提供的getBean,还有其他方法,所以我们不能光看一个接口,还要看它的具体实现类

在这里我们就只看它的DefaultSingletonBeanRegistry接口中的单例对象,这个为大家比较熟悉的,来看源码:

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements 
SingletonBeanRegistry {
    /** Maximum number of suppressed exceptions to preserve. */
    /**
     * 抑制异常数量最大值
     */
    private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;
    /** 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. */
    /**
     * 三级缓存 该map用户缓存 key为 beanName  value 为ObjectFactory(包装为早期对象)
     */
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    /** Cache of early singleton objects: bean name to bean instance. */
    /**
     * 二级缓存 ,用户缓存我们的key为beanName value是我们的早期对象
     (对象属性还没有来得及进行赋值)
     */
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
    /** Set of registered singletons, containing the bean names in registration order. */
    /**
     * 已注册的单例名称set
     */
    private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
    /** Names of beans that are currently in creation. */
    /**
     * 该集合用于缓存当前正在创建bean的名称
     */
    private final Set<String> singletonsCurrentlyInCreation =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    /** Names of beans currently excluded from in creation checks. */
    /**
     * 排除当前创建检查的
     */
    private final Set<String> inCreationCheckExclusions =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    /**
     * Collection of suppressed Exceptions, available for associating related causes.
     */
    @Nullable
    /**抑制异常的集合,可用于关联相关原因*/
    private Set<Exception> suppressedExceptions;
    /** Flag that indicates whether we're currently within destroySingletons. */
    /**
     * 指示我们当前是否在 destroySingletons 中的标志。
     */
    private boolean singletonsCurrentlyInDestruction = false;
    /** Disposable bean instances: bean name to disposable instance. */
    /**
     * 用于缓存记录实现了DisposableBean 接口的实例
     */
    private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
    /** Map between containing bean names: bean name to Set of bean names that the bean contains. */
    /**
     * 缓存bean的属性关系的映射<service,<aDao,bDa>>
     */
    private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
    /** Map between dependent bean names: bean name to Set of dependent bean names. */
    /**
     * 保存的是依赖 beanName 之间的映射关系:beanName - > 依赖 beanName 的集合
     */
    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. */
    /**
     * 保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
     */
    private final Map<String, Set<String>> dependenciesForBeanMap = 
    new ConcurrentHashMap<>(64);
    /**
     * 注册单例Bean
     *
     * @param beanName        the name of the bean
     * @param singletonObject the existing singleton object
     * @throws IllegalStateException
     */
    @Override
    public void registerSingleton(String beanName, Object singletonObject) 
    throws IllegalStateException {
        //断言beanName是否为空
        Assert.notNull(beanName, "Bean name must not be null");
        //断言singletonObject是否为空
        Assert.notNull(singletonObject, "Singleton object must not be null");
        synchronized (this.singletonObjects) {
            //从一级缓存中通过beanName拿取Bean
            Object oldObject = this.singletonObjects.get(beanName);
            //一级缓存中存在了,抛出IllegalStateException
            if (oldObject != null) {
                throw new IllegalStateException("Could not register object 
                [" + singletonObject +
                        "] under bean name '" + beanName + "': there is already object 
                        [" + oldObject + "] bound");
            }
            //如果不存在,将singletonObject添加到一级缓存
            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) {
            //将singletonObject添加到一级缓存中,同时移除二级、三级缓存、并标记当前Bean已注册
            this.singletonObjects.put(beanName, singletonObject);
            //移除三级缓存
            this.singletonFactories.remove(beanName);
            //移除二级缓存
            this.earlySingletonObjects.remove(beanName);
            //标记当前Bean已被注册
            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.
     * 该方法用于把早期对象包装成一个ObjectFactory 暴露到三级缓存中 用于将解决循环依赖...
     *
     * @param beanName         the name of the bean
     * @param singletonFactory the factory for the singleton object
     */
    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        //断言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);
                //标记当前Bean已经被注册过
                this.registeredSingletons.add(beanName);
            }
        }
    }
    /**
     * 该方法是一个空壳方法
     *
     * @param beanName the name of the bean to look for
     * @return 缓存中的对象(有可能是一个单例完整对象, 也有可能是一个早期对象 
     ( 用于解决循环依赖))
     */
    @Override
    @Nullable
    public Object getSingleton(String beanName) {
        //在这里 系统一般是允许早期对象引用的 allowEarlyReference通过这个参数可以控制解决循环依赖
        return getSingleton(beanName, true);
    }
    /**
     * 在网上很多很多写源码的大佬或者是<spring源码深度解析>一书上,也没有说清楚为啥要使用三级缓存
     (二级缓存可不可以能够
     * 解决) 答案是:可以, 但是没有很好的扩展性为啥这么说.......
     * 原因: 获取三级缓存-----getEarlyBeanReference()经过一系列的后置处理来给我们早期对象进行特
     殊化处理
     * //从三级缓存中获取包装对象的时候 ,他会经过一次后置处理器的处理对我们早期对象的bean进行
     * 特殊化处理,但是spring的原生后置处理器没有经过处理,而是留给了我们程序员进行扩展
     * singletonObject = singletonFactory.getObject();
     * 把三级缓存移植到二级缓存中
     * this.earlySingletonObjects.put(beanName, singletonObject);
     * //删除三级缓存中的之
     * this.singletonFactories.remove(beanName);
     *
     * @param beanName            bean的名称
     * @param allowEarlyReference 是否允许暴露早期对象  通过该参数可以控制是否能够解决循环依赖的.
     * @return 这里可能返回一个null(IOC容器加载单实例bean的时候,第一次进来是返回null)
     * 也有可能返回一个单例对象(IOC容器加载了单实例了,第二次来获取当前的Bean)
     * 也可能返回一个早期对象(用于解决循环依赖问题)
     */
    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // Quick check for existing instance without full singleton lock
        /**
         * 第一步:我们尝试去一级缓存(单例缓存池中去获取对象,一般情况从该map中获取的对象是直接
         可以使用的)
         * IOC容器初始化加载单实例bean的时候第一次进来的时候 该map中一般返回空
         */
        Object singletonObject = this.singletonObjects.get(beanName);
        //如果一级缓存为空,并且标记正在创建
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            /**
             * 尝试去二级缓存中获取对象(二级缓存中的对象是一个早期对象)
             * 何为早期对象:就是bean刚刚调用了构造方法,还来不及给bean的属性进行赋值的对象
             (纯净态)
             * 就是早期对象
             */
            singletonObject = this.earlySingletonObjects.get(beanName);
            /**
             * 二级缓存中也没有获取到对象,allowEarlyReference为true
             (参数是有上一个方法传递进来的true)
             */
            if (singletonObject == null && allowEarlyReference) {
                synchronized (this.singletonObjects) {
                    // Consistent creation of early reference within full singleton lock
                    /**
                     * 再次尝试从一级缓存中去拿,如果还是没拿到则尝试去二级缓存中拿
                     */
                    singletonObject = this.singletonObjects.get(beanName);
                    //一级缓存中没拿到
                    if (singletonObject == null) {
                        //尝试从二级缓存中去拿
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        //二级缓存还是空
                        if (singletonObject == null) {
                            /**
                             * 直接从三级缓存中获取 ObjectFactory对象 这个对接就是用来解决循环
                             依赖的关键所在
                             * 在ioc后期的过程中,当bean调用了构造方法的时候,把早期对象包裹成一
                             个ObjectFactory
                             * 暴露到三级缓存中
                             */
                            ObjectFactory<?> singletonFactory = this.singletonFactories.get
                            (beanName);
                            //三级缓存中获取的对象不为空
                            if (singletonFactory != null) {
                                /**
                                 * 在这里通过暴露的ObjectFactory 包装对象中,通过调用他的
                                 getObject()来获取我们的早期对象
                                 * 在这个环节中会调用到 getEarlyBeanReference()来进行后置处理
                                 */
                                singletonObject = singletonFactory.getObject();
                                //把早期对象放置在二级缓存,
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                //ObjectFactory 包装对象从三级缓存中删除掉
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }
        //返回这个Bean
        return singletonObject;
    }
    /**
     * Return the (raw) singleton object registered under the given name,
     * creating and registering a new one if none registered yet.
     * 获取单例对象(该流程用于触发构建bean)
     *
     * @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) {
        //断言beanName不为空
        Assert.notNull(beanName, "Bean name must not be null");
        //同步加锁
        synchronized (this.singletonObjects) {
            //尝试从一级缓存池中获取对象
            Object singletonObject = this.singletonObjects.get(beanName);
            //从一级缓存中没拿到
            if (singletonObject == null) {
                //当前是否是正在销毁,是的话抛出BeanCreationNotAllowedException异常
                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!)");
                }
                //判断是否已启用Debug调试模式
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName 
                    + "'");
                }
                /**
                 * 标记当前的bean马上就要被创建了
                 * singletonsCurrentlyInCreation 在这里会把beanName加入进来,若第二次循环依赖
                 (构造器注入会抛出异常)
                 */
                beforeSingletonCreation(beanName);
                //标记是否为新创建的单例Bean
                boolean newSingleton = false;
                //标记是否记录抑制异常
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                //如果为空,创建抑制异常集合
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    // 初始化 bean
                    // 这个过程其实是调用 createBean() 方法
                    singletonObject = singletonFactory.getObject();
                    //标记这个Bean是新创建的
                    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;
                    }
                    //后置处理
                    //主要做的事情就是把singletonsCurrentlyInCreation标记正在创建的bean从集合中
                    移除
                    afterSingletonCreation(beanName);
                }
                //是新建的单例Bean,添加到一级缓存中去
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);
                }
            }
            //返回单例Bean
            return singletonObject;
        }
    }
    /**
     * Register an exception that happened to get suppressed during the creation of a
     * singleton bean instance, e.g. a temporary circular reference resolution problem.
     * <p>The default implementation preserves any given exception in this registry's
     * collection of suppressed exceptions, up to a limit of 100 exceptions, adding
     * them as related causes to an eventual top-level {@link BeanCreationException}.
     * 注册在创建单例 bean 实例期间碰巧被抑制的异常,例如一个临时的循环引用解析问题。
     *
     * @param ex the Exception to register
     * @see BeanCreationException#getRelatedCauses()
     */
    protected void onSuppressedException(Exception ex) {
        synchronized (this.singletonObjects) {
            //抑制异常集合不为空,且小于SUPPRESSED_EXCEPTIONS_LIMIT最大限制
            if (this.suppressedExceptions != null && this.suppressedExceptions.size() 
            < SUPPRESSED_EXCEPTIONS_LIMIT) {
                //向抑制集合中添加异常
                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.
     * 从该工厂的单例缓存中删除bean ,以便能够在创建失败时清除单例的急切注册。
     *
     * @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);
            //从Bean注册标记集合中移除
            this.registeredSingletons.remove(beanName);
        }
    }
    /**
     * 一级缓存中是否存在该Bean
     *
     * @param beanName the name of the bean to look for
     * @return
     */
    @Override
    public boolean containsSingleton(String beanName) {
        //判断一级缓存中是否存在该Bean
        return this.singletonObjects.containsKey(beanName);
    }
    /**
     * 获取已注册的单例Bean名字的集合
     *
     * @return
     */
    @Override
    public String[] getSingletonNames() {
        synchronized (this.singletonObjects) {
            //获取已注册的单例Bean名字的集合
            return StringUtils.toStringArray(this.registeredSingletons);
        }
    }
    /**
     * 获取已注册单例Bean实例的个数
     *
     * @return
     */
    @Override
    public int getSingletonCount() {
        synchronized (this.singletonObjects) {
            //获取已注册单例Bean实例的个数
            return this.registeredSingletons.size();
        }
    }
    /**
     * 标记当前Bean正在创建,主要解决循环依赖
     *
     * @param beanName   Bean名字
     * @param inCreation 是否已标记
     */
    public void setCurrentlyInCreation(String beanName, boolean inCreation) {
        //断言Bean不为空
        Assert.notNull(beanName, "Bean name must not be null");
        //如果未标记,将beanName加到inCreationCheckExclusions集合中,已标记则移除
        if (!inCreation) {
            this.inCreationCheckExclusions.add(beanName);
        } else {
            this.inCreationCheckExclusions.remove(beanName);
        }
    }
    /**
     * 返回当前Bean是否是正在创建
     *
     * @param beanName
     * @return
     */
    public boolean isCurrentlyInCreation(String beanName) {
        Assert.notNull(beanName, "Bean name must not be null");
        return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation
        (beanName));
    }
    /**
     * 返回当前Bean实际上是否在创建中
     *
     * @param beanName
     * @return
     */
    protected boolean isActuallyInCreation(String beanName) {
        return isSingletonCurrentlyInCreation(beanName);
    }
    /**
     * Return whether the specified singleton bean is currently in creation
     * (within the entire factory).
     * 返回指定的单例 bean 当前是否正在创建中
     *
     * @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.
     * 单例Bean创建前回调方法,默认实现将单例注册为当前正在创建中
     *
     * @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).
     * 将给定的 bean 添加到此注册表中的一次性 bean 列表中。 一次性 bean 通常对应于已注册的单例,
     * 与 bean 名称匹配,但可能是不同的实例(例如,单例的 DisposableBean 
     适配器不自然实现 Spring 的 DisposableBean 接口)。
     *
     * @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.
     * 注册两个 bean 之间的包含关系,例如在内部 bean 和包含它的外部 bean 之间。
     还根据销毁顺序将包含的 bean 注册为依赖于所包含的 bean。
     *
     * @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)
     {
        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
     */
    public void registerDependentBean(String beanName, String dependentBeanName) {
        //获取原始的beanName
        String canonicalName = canonicalName(beanName);
        // 添加 <canonicalName, <dependentBeanName>> 到 dependentBeanMap 中
        synchronized (this.dependentBeanMap) {
            Set<String> dependentBeans =
                    this.dependentBeanMap.computeIfAbsent(canonicalName,
                     k -> new LinkedHashSet<>(8));
            if (!dependentBeans.add(dependentBeanName)) {
                return;
   &nb                
                
                        
					
                
                

相关推荐

PHP实现部分字符隐藏

沙雕mars · 1323浏览 · 2019-04-28 09:47:56
Java中ArrayList和LinkedList区别

kenrry1992 · 906浏览 · 2019-05-08 21:14:54
Tomcat 下载及安装配置

manongba · 966浏览 · 2019-05-13 21:03:56
JAVA变量介绍

manongba · 960浏览 · 2019-05-13 21:05:52
什么是SpringBoot

iamitnan · 1084浏览 · 2019-05-14 22:20:36
加载中

0评论

评论
我从事编程工作,现在在一家网络公司上班,偶尔也是发布博客,逛论坛等,希望可以在这里交到志同道合的朋友。
分类专栏
小鸟云服务器
扫码进入手机网页