BeanDefinitionRegistry接口

这个接口扩大了上文提到的别名注册接口,提供了bean定义的注册,登记等性能

public interface BeanDefinitionRegistry extends AliasRegistry {    //注册bean定义,可能抛出异样    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)            throws BeanDefinitionStoreException;    //登记bean定义,可能抛出异样    void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;    //获取bean定义    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;    //是否蕴含bean定义    boolean containsBeanDefinition(String beanName);    //获取所有bean定义的名字    String[] getBeanDefinitionNames();    //返回bean定义的总数    int getBeanDefinitionCount();    //是否给定的bean在应用了    boolean isBeanNameInUse(String beanName);}

DefaultListableBeanFactory实现

尽管还有一些别的实现,但咱们beanFactory的剖析整个都是基于DefaultListableBeanFactory的继承体系来剖析的,能够看到这个类间接实现了咱们的bean定义注册接口,上面剖析它的相干实现

与bean定义无关的属性

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

registerBeanDefinition

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)            throws BeanDefinitionStoreException {        if (beanDefinition instanceof AbstractBeanDefinition) {            try {            //验证bean定义                ((AbstractBeanDefinition) beanDefinition).validate();            }            catch (BeanDefinitionValidationException ex) {                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,                        "Validation of bean definition failed", ex);            }        }        BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);        if (existingDefinition != null) {        //是否容许bean定义重写是能够配置的            if (!isAllowBeanDefinitionOverriding()) {                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);            }            this.beanDefinitionMap.put(beanName, beanDefinition);        }        else {        //是否曾经创立了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<>(this.beanDefinitionNames.size() + 1);                    updatedDefinitions.addAll(this.beanDefinitionNames);                    updatedDefinitions.add(beanName);                    this.beanDefinitionNames = updatedDefinitions;                    removeManualSingletonName(beanName);                }            }            else {                // Still in startup registration phase                this.beanDefinitionMap.put(beanName, beanDefinition);                this.beanDefinitionNames.add(beanName);                //移除手动单例名字,将注册的bean定义优先级更高                removeManualSingletonName(beanName);            }            //无论如何,冻结已解冻的bean定义            this.frozenBeanDefinitionNames = null;        }        //如果原本就存在bean定义,或者这个bean曾经处于创立中了,须要重置bean定义        if (existingDefinition != null || containsSingleton(beanName)) {            resetBeanDefinition(beanName);        }        else if (isConfigurationFrozen()) {            clearByTypeCache();        }    }

有几个要留神的中央
1.((AbstractBeanDefinition) beanDefinition).validate()

bean定义除了这个形象bean定义还是基于注解的bean定义,只有在形象bean定义的时候才会去做验证,前面在剖析这个办法
2.在往map增加新数据前有个hasBeanCreationStarted办法
如果都没有创立好的bean,阐明以后肯定没有对beanName汇合的遍历,要晓得遍历的时候去增加数据是不稳固的,有可能抛出并发批改异样,所以这里通过这个办法来判断。集体了解,深入分析当前也没察觉这个办法是线程平安的,感觉又不是这个起因?
3.后续解决:旧的bean定义存在,或者单例的bean曾经在创立中
这种状况意味着对旧的bean定义重写了,但什么时候会呈现没有旧的bean定义然而单例bean曾经在创立了呢?能够看到有一条要害门路就是重置bean定义,这里能够认为是做一些清理工作,比方移除合并后的bean定义
protected void resetBeanDefinition(String beanName) {        //如果曾经被创立,移除合并后的bean定义        clearMergedBeanDefinition(beanName);        //移除缓存的单例        destroySingleton(beanName);        //告诉所有的后置处理器,指定的bean定义被重置了        for (BeanPostProcessor processor : getBeanPostProcessors()) {            if (processor instanceof MergedBeanDefinitionPostProcessor) {                ((MergedBeanDefinitionPostProcessor) processor).resetBeanDefinition(beanName);            }        }        // 递归重置所有的子bean定义        for (String bdName : this.beanDefinitionNames) {            if (!beanName.equals(bdName)) {                BeanDefinition bd = this.beanDefinitionMap.get(bdName);                // Ensure bd is non-null due to potential concurrent modification of beanDefinitionMap.                if (bd != null && beanName.equals(bd.getParentName())) {                    resetBeanDefinition(bdName);                }            }        }    }

removeBeanDefinition

这里相似于注册,不再剖析

public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {        BeanDefinition bd = this.beanDefinitionMap.remove(beanName);        if (bd == null) {            throw new NoSuchBeanDefinitionException(beanName);        }        if (hasBeanCreationStarted()) {            synchronized (this.beanDefinitionMap) {                List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames);                updatedDefinitions.remove(beanName);                this.beanDefinitionNames = updatedDefinitions;            }        }        else {            // Still in startup registration phase            this.beanDefinitionNames.remove(beanName);        }        this.frozenBeanDefinitionNames = null;        resetBeanDefinition(beanName);    }

getBeanDefinitionNames

这里有意思的是如果已解冻的bean定义列表有数据,就返回这个,否则就返回实时的bean定义列表数据,至于为何这么做有待思考。

    public String[] getBeanDefinitionNames() {        String[] frozenNames = this.frozenBeanDefinitionNames;        if (frozenNames != null) {            return frozenNames.clone();        }        else {            return StringUtils.toStringArray(this.beanDefinitionNames);        }    }

isBeanNameInUse

这个办法实现并不在DefaultListableBeanFactory中,因为DefaultListableBeanFactory还继承了AbstractBeanFactory,在它的形象父类中实现了该办法,这也阐明接口中的办法不肯定要在一个类中全副实现,只有可能保障通过继承实现也是能够的!

public boolean isBeanNameInUse(String beanName) {        return isAlias(beanName) || containsLocalBean(beanName) || hasDependentBean(beanName);    }

这个逻辑并不简单,也就是判断beanName是否被别名占用了,容器本地是否蕴含了beanName,beanName是否是某一个bean的依赖