疑问 1:
@Override 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 { ((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) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { 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); removeManualSingletonName(beanName); } this.frozenBeanDefinitiOnNames= null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } else if (isConfigurationFrozen()) { clearByTypeCache(); } }
其中这一段代码
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
else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); }
希望大家能给解答一下,万分感谢 !
![]() | 1 shanghai1943 2023-08-30 10:50:10 +08:00 ![]() claude ai 的回复 hasBeanCreationStarted() 方法是用来判断 bean 定义注册是否处于启动阶段。 在 Spring 容器启动时,会有一个 bean 定义注册的过程,这个过程称为启动阶段。启动阶段结束后,会调用 finishBeanFactoryInitialization() 方法,设置启动阶段完成的标记。 之所以需要判断启动阶段,是因为在启动阶段和非启动阶段,bean 定义的注册逻辑有略微不同: 1. 启动阶段:可以直接修改 beanDefinitionMap 和 beanDefinitionNames 2. 非启动阶段:需要同步处理,避免多线程并发访问这些容器内存状态 else 分支就是处理非启动阶段的逻辑。当容器已经完成了启动,这个时候再注册 bean 定义,就需要加锁处理: 1. 同步包装 beanDefinitionMap 的修改 2. 创建 beanDefinitionNames 的拷贝进行修改 3. 删除 manualSingletonNames 里的对应名称 之所以这么设计,是因为启动阶段内存状态的变更频繁,如果都加锁处理会非常低效。所以启动阶段只 simply 修改状态,结束后再对状态变更加锁。 而 hasBeanCreationStarted()就是判断当前是否还在启动阶段,从而决定走哪种 bean 定义注册逻辑。 所以这个判断对提高整个容器的并发性能很重要。 |
![]() | 2 liuyunlong OP 清晰明了,万分感谢 |