美文网首页
BeanDefinition的注册

BeanDefinition的注册

作者: 码而优则仕 | 来源:发表于2020-09-28 08:21 被阅读0次

    BeanDefinition的注册

    根据 beanName注册 beanDefinition,

    bean 的 name 首先取 定义的 id,如果id未定义且存在别名列表,就取第一个别名作为 bean 的 name,如果根据id 和别名列表都没有找到 bean 的名称则根据 Spring bean 名称的生成规则生成该 bean 的名称。

    注册BeanDefinition前还需要做最后的校验,如果BeanDefinition 是 AbstractBeanDefinition的话 需要校验 methodOverrides 是否与工厂方法并存,如果共存就直接报错;如果当前 Bean对应的 Class对象存在,则检查 methodOverrides 中的方法在 该 bean对应的 Class中是否存在,如果不存在则直接报错,如果存在且只有一个的话就标记 不存在重载,因为如果方法有多个存在的话调用就有多态的问题,需要确定调哪个。

    以下结构用于存储容器中所有注册的 BeanDefinition

    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
    

    首先 根据 beanName 从 Map中查看是否已经有同名的 bean,

    如果存在同名的 bean已经被注册了且不允许后者覆盖前者的话就直接报错。默认是允许覆盖的。如果 允许覆盖则比较已经注册 的 BeanDefinition 的 role和准备注册 的 BeanDefinition 如果准备注册的 role大于已经注册的则报警提示使用 系统生成的 bean替换历史bean,如果是不同的bean 则打信息日志提示使用不同的beanDefinition替换了原来的 bean;然后直接将最新的 BeanDefinition put进 map中。

    private boolean allowBeanDefinitionOverriding = true;
    

    如果不存在则 看看是否有已经注册过的 bean 如果有就对这个全局Map变量进行加锁操作。然后再注册,注册后按照 CopyOnWrite的方式 更新 beanDefinitionNames 列表 添加新注册 的 bean ,如果手动注册的单例 bean中包含当前注册的 bean 也按照 CopyOnWrite 的方式 移除该 bean

    if (hasBeanCreationStarted()) {
       // Cannot modify startup-time collection elements anymore (for stable iteration)
       synchronized (this.beanDefinitionMap) {
          this.beanDefinitionMap.put(beanName, beanDefinition);
          List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
          updatedDefinitions.addAll(this.beanDefinitionNames);
          updatedDefinitions.add(beanName);
          this.beanDefinitionNames = updatedDefinitions;
          if (this.manualSingletonNames.contains(beanName)) {
             Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
             updatedSingletons.remove(beanName);
             this.manualSingletonNames = updatedSingletons;
          }
       }
    }
    

    已经注册的 BeanName列表

    private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
    

    手动注册的单利 bean列表

    private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);
    

    如果已经注册过的 bean列表为空则直接 注册 和修改上面提到的两个列表

    else {
       // Still in startup registration phase
       this.beanDefinitionMap.put(beanName, beanDefinition);
       this.beanDefinitionNames.add(beanName);
       this.manualSingletonNames.remove(beanName);
    }
    

    如果当前注册的 beanName已经被注册过或者 单利 bean 列表中包含当前注册 的 bean则

    if (oldBeanDefinition != null || containsSingleton(beanName)) {
       resetBeanDefinition(beanName);
    }
    
    /**
         * Reset all bean definition caches for the given bean,
         * including the caches of beans that are derived from it.
         * @param beanName the name of the bean to reset
         */
        protected void resetBeanDefinition(String beanName) {
            // Remove the merged bean definition for the given bean, if already created.
            clearMergedBeanDefinition(beanName);
    
            // Remove corresponding bean from singleton cache, if any. Shouldn't usually
            // be necessary, rather just meant for overriding a context's default beans
            // (e.g. the default StaticMessageSource in a StaticApplicationContext).
            destroySingleton(beanName);
    
            // Reset all bean definitions that have the given bean as parent (recursively).
            for (String bdName : this.beanDefinitionNames) {
                if (!beanName.equals(bdName)) {
                    BeanDefinition bd = this.beanDefinitionMap.get(bdName);
                    if (beanName.equals(bd.getParentName())) {
                        resetBeanDefinition(bdName);
                    }
                }
            }
        }
        
        
        /**
         * Remove the merged bean definition for the specified bean,
         * recreating it on next access.
         * @param beanName the bean name to clear the merged definition for
         */
        protected void clearMergedBeanDefinition(String beanName) {
            this.mergedBeanDefinitions.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
         */
        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);
        }
    
    
    /**
         * 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);
            }
        }
        
        
        
        /**
         * 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);
        }
    
    /** Map from bean name to merged RootBeanDefinition */
    private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
          new ConcurrentHashMap<String, RootBeanDefinition>(256);
    
        /** Cache of singleton objects: bean name --> bean instance */
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
    
        /** 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);
    
    /** Disposable bean instances: bean name --> disposable instance */
    private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
    
    /** 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);
    

    相关文章

      网友评论

          本文标题:BeanDefinition的注册

          本文链接:https://www.haomeiwen.com/subject/mamluktx.html