09.Spring Bean 注册

基本概念

BeanDefinitionRegistry ,该类的作用主要是向注册表中注册 BeanDefinition 实例,完成 注册的过程。

它的接口定义如下:

public interface BeanDefinitionRegistry extends AliasRegistry {

    // 关键 -> 往注册表中注册一个新的 BeanDefinition 实例 
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;

    // 移除注册表中已注册的 BeanDefinition 实例
    void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    // 从注册中取得指定的 BeanDefinition 实例
    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    // 判断 BeanDefinition 实例是否在注册表中(是否注册)
    boolean containsBeanDefinition(String beanName);

    // 取得注册表中所有 BeanDefinition 实例的 beanName(标识)
    String[] getBeanDefinitionNames();

    // 返回注册表中 BeanDefinition 实例的数量
    int getBeanDefinitionCount();

    // beanName(标识)是否被占用
    boolean isBeanNameInUse(String beanName);

}

再来看它的继承关系:

这里写图片描述


2.DefaultListableBeanFactory

该类是 BeanDefinitionRegistry 接口的基本实现类,但同时也实现其他了接口的功能,这里只探究下其关于注册 BeanDefinition 实例的相关方法 。

首先来看它的成员变量:

// 关键-> 注册表,由 BeanDefinition 的标识 (beanName) 与其实例组成
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, bean>(64);

// 标识(beanName)集合
private final List<String> beanDefinitionNames = new ArrayList<String>(64);

再来看 BeanDefinitionReaderUtils 的 registerBeanDefinition 方法。该方法的主要作用是调用注册器(DefaultListableBeanFactory)完成注册过程。

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    throws BeanDefinitionStoreException {

    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");

    if (beanDefinition instanceof AbstractBeanDefinition) {
        try {
            // BeanDefinition 校验
            ((AbstractBeanDefinition) beanDefinition).validate();

        }catch (BeanDefinitionValidationException ex) {
            // 抛出异常...
        }
    }

    BeanDefinition oldBeanDefinition;

    oldBeanDefinition = this.beanDefinitionMap.get(beanName);
    if (oldBeanDefinition != null) {
        if (!isAllowBeanDefinitionOverriding()) {
            // 抛出异常...
        }else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
            // 日志输出...
        }
        else if (!beanDefinition.equals(oldBeanDefinition)) {
            // 日志输出...
        }
        else {
            // 日志输出...
        }
    }else {
        // 添加标识进 List
        this.beanDefinitionNames.add(beanName);
        this.manualSingletonNames.remove(beanName);
        this.frozenBeanDefinitionNames = null;
    }

    // 关键 -> 添加进 map
    this.beanDefinitionMap.put(beanName, beanDefinition);

    if (oldBeanDefinition != null || containsSingleton(beanName)) {
        resetBeanDefinition(beanName);
    }
}

观察代码可以发现该方法最重要的步骤其实就是:

this.beanDefinitionMap.put(beanName, beanDefinition);

也就是向注册表中(beanDefinitionMap)添加 BeanDefinition 实例,完成注册的过程。

原文地址:https://www.cnblogs.com/moxiaotao/p/9349549.html