zoukankan      html  css  js  c++  java
  • 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 实例,完成注册的过程。

  • 相关阅读:
    Java8常用新特性实践
    Presto集群部署
    Exception: Unexpected End Of File(crontab)
    centos6环境下使用yum安装Ambari
    pyspark进行词频统计并返回topN
    七行代码开始flask
    hibernate初步4
    java四大域总结
    servlet中的转发和重定向问题
    一个web页面的访问的过程
  • 原文地址:https://www.cnblogs.com/moxiaotao/p/9349549.html
Copyright © 2011-2022 走看看