Spring的Bean定义注册中心BeanDefinitionRegistry

一、BeanDefinitionRegistry

   BeanDefinitionRegistry是一个接口继承AliasRegistry接口(别名处理)  

public interface BeanDefinitionRegistry extends AliasRegistry {

    /**    在这个注册表中注册一个新的bean定义
     */
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException;

    /**
    删除给定名称的BeanDefinition*/
    void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    /**
    返回给定bean名称的BeanDefinition*/
    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    /**
    检查注册表是否包含给定名称的bean定义*/
    boolean containsBeanDefinition(String beanName);

    /**
    返回该注册表中定义的所有bean的名称*/
    String[] getBeanDefinitionNames();

    /**
    返回注册表中定义的bean定义的数量*/
    int getBeanDefinitionCount();

    /**
    给定的bean名是否已经在这个注册表中使用*/
    boolean isBeanNameInUse(String beanName);

}

二、BeanDefinitionRegistry的实现类

    

  1、SimpleBeanDefinitionRegistry

    

public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {

    /** Map of bean definition objects, keyed by bean name. */
  //存储bean的定义线程安全
  private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64);
  
   //注册bean的定义
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {

        Assert.hasText(beanName, "'beanName' must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        this.beanDefinitionMap.put(beanName, beanDefinition);
    }

    //根据名称删除bean的定义   没有定义抛出异常
    public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
        if (this.beanDefinitionMap.remove(beanName) == null) {
            throw new NoSuchBeanDefinitionException(beanName);
        }
    }

    //获取bean的定义
    public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
        BeanDefinition bd = this.beanDefinitionMap.get(beanName);
        if (bd == null) {
            throw new NoSuchBeanDefinitionException(beanName);
        }
        return bd;
    }

    //
    public boolean containsBeanDefinition(String beanName) {
        return this.beanDefinitionMap.containsKey(beanName);
    }

    //
    public String[] getBeanDefinitionNames() {
        return StringUtils.toStringArray(this.beanDefinitionMap.keySet());
    }

    //
    public int getBeanDefinitionCount() {
        return this.beanDefinitionMap.size();
    }

    //
    public boolean isBeanNameInUse(String beanName) {
        return isAlias(beanName) || containsBeanDefinition(beanName);
    }

}

 

  2 、DefaultListableBeanFactory

  

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    ...
    /** Map of bean definition objects, keyed by bean name */  存bean的定义 线程安全
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    // 保存所有的Bean名称
    /** List of bean definition names, in registration order */
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

    // 注册Bean定义信息~~
    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
        ...
        BeanDefinition oldBeanDefinition = this.beanDefinitionMap.get(beanName);
        // 如果不为null,说明这个beanName对应的Bean定义信息已经存在了~~~~~
        if (oldBeanDefinition != null) {
            // 是否允许覆盖(默认是true 表示允许的)
            if (!isAllowBeanDefinitionOverriding()) {
                // 抛异常
            }
            // 若允许覆盖  那还得比较下role  如果新进来的这个Bean的role更大            
            // 比如老的是ROLE_APPLICATION(0)  新的是ROLE_INFRASTRUCTURE(2) 
            // 最终会执行到put,但是此处输出一个warn日志,告知你的bean被覆盖啦~~~~~~~(我们自己覆盖Spring框架内的bean显然就不需要warn提示了)
            else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
                // 仅仅输出一个logger.warn
            }
            // 最终会执行put,但是内容还不相同  那就提醒一个info信息吧
            else if (!beanDefinition.equals(oldBeanDefinition)) {
                // 输出一个info信息
            }
            else {
                // 输出一个debug信息
            }
            // 最终添加进去 (哪怕已经存在了~) 
            // 从这里能看出Spring对日志输出的一个优秀处理,方便我们定位问题~~~
            this.beanDefinitionMap.put(beanName, beanDefinition);
            // 请注意:这里beanName并没有再add了,因为已经存在了  没必要了嘛
        }
        else {
            // hasBeanCreationStarted:表示已经存在bean开始创建了(开始getBean()了吧~~~)
            if (hasBeanCreationStarted()) {
                // 注册过程需要synchronized,保证数据的一致性    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;
            
                    // 
                    if (this.manualSingletonNames.contains(beanName)) {
                        Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;
                    }
                }
            }
            else {
                // Still in startup registration phase
                // 表示仍然在启动  注册的状态~~~就很好处理了 put仅需,名字add进去
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                
                // 手动注册的BeanNames里面移除~~~ 因为有Bean定义信息了,所以现在不是手动直接注册的Bean单例~~~~
                this.manualSingletonNames.remove(beanName);
            }

            // 这里的意思是:但凡你新增了一个新的Bean定义信息,之前已经冻结的就清空呗~~~
            this.frozenBeanDefinitionNames = null;
        }
        
        // 最后异步很有意思:老的bean定义信息不为null(beanName已经存在了),或者这个beanName直接是一个单例Bean了~
        if (oldBeanDefinition != null || containsSingleton(beanName)) {
            // 做清理工作:
            // clearMergedBeanDefinition(beanName)
            // destroySingleton(beanName);  销毁这个单例Bean  因为有了该bean定义信息  最终还是会创建的
            // Reset all bean definitions that have the given bean as parent (recursively).  处理该Bean定义的getParentName  有相同的也得做清楚  所以这里是个递归
            resetBeanDefinition(beanName);
        }
    }

    @Override
    public void removeBeanDefinition(String beanName) throws         NoSuchBeanDefinitionException {
        // 移除整体上比较简单:beanDefinitionMap.remove
        // beanDefinitionNames.remove
        // resetBeanDefinition(beanName);

        BeanDefinition bd = this.beanDefinitionMap.remove(beanName);
        // 这里发现移除,若这个Bean定义本来就不存在,事抛异常,而不是返回null 需要注意~~~~
        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 {
            this.beanDefinitionNames.remove(beanName);
        }
        this.frozenBeanDefinitionNames = null;
        resetBeanDefinition(beanName);
    }

    // 获取bean的定义
    @Override
    public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
        BeanDefinition bd = this.beanDefinitionMap.get(beanName);
        if (bd == null) {
            throw new NoSuchBeanDefinitionException(beanName);
        }
        return bd;
    }

@Override
    public boolean containsBeanDefinition(String beanName) {
        return this.beanDefinitionMap.containsKey(beanName);
    }
    @Override
    public int getBeanDefinitionCount() {
        return this.beanDefinitionMap.size();
    }
    @Override
    public String[] getBeanDefinitionNames() {
        String[] frozenNames = this.frozenBeanDefinitionNames;
        if (frozenNames != null) {
            return frozenNames.clone();
        }
        else {
            return StringUtils.toStringArray(this.beanDefinitionNames);
        }
    }
    
}

三、GenericApplicationContext

  1、GenericApplicationContext 的属性

  

  //bean工厂  上面第二个实现类
private final DefaultListableBeanFactory beanFactory;   //读取配置文件 @Nullable private ResourceLoader resourceLoader;    private boolean customClassLoader = false; //线程安全 boolean private final AtomicBoolean refreshed = new AtomicBoolean();

 

  2、手动创建bean

      GenericApplicationContext ctx = new GenericApplicationContext();
        //手动使用XmlBeanDefinitionReader
        XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
        //加载ClassPathResource
        xmlReader.loadBeanDefinitions(new ClassPathResource("spring.xml"));//调用Refresh方法 启动容器
        ctx.refresh();

        //和其他ApplicationContext方法一样的使用方式   实体类为spring.xml中bean对象
        System.out.println(ctx.getBean("person")); 

 

posted @ 2020-09-18 17:39  StrangerIt  阅读(477)  评论(0)    收藏  举报