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"));

浙公网安备 33010602011771号