BeanDefinition注册逻辑解析

//调用:BeanDefinitionReaderUtils.registerBeanDefinition
//最终实现:org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
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 {
				// 校验,注册前的最后一次校验,这里主要对methodOverrides 属性进行校验
				// 看定义的对应的类和和方法是否存在
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
		// 获取之前以当前bean名称注册的beanDefinition
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		// 如果注册过
		if (existingDefinition != null) {
			// 如果不允许bean定义覆盖,则抛出异常
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			} // 如果角色被内部的beanDefinition覆盖,记录修改到日志
			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 + "]");
				}
			} // 两个bean不同,记录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 + "]");
				}
			}// 最终只淡出的记录一下beanDefinition 覆盖记录
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}

			// 将新的beanDefinition记录到beanDefinitionMap中
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		// 如果之前未注册过beanDefinition
		else {
			// 如果已经有bean创建过了(不一定是当前bean)
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					// 将beanDefinition 放入缓存
					this.beanDefinitionMap.put(beanName, beanDefinition);
					// 更新beanDefinitionNames,将当前的元素添加进去
					// 这里没有锁 beanDefinitionNames,是否存在并发问题:
					// 不会,对beanDefinitionNames的修改,锁的都是beanDefinitionMap,没有问题
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					// 移除已经手动注册的单例bean
					removeManualSingletonName(beanName);
				}
			}
			else {
				// Still in startup registration phase
				// 没有bean被初始化过,注册解析的beanDefinition
				this.beanDefinitionMap.put(beanName, beanDefinition);
				// 记录已经解析过得beanDefinition,这里没有并发问题,因为在这种case 还在开始的注册阶段,不用加锁
				this.beanDefinitionNames.add(beanName);
				// 再移除一遍 已经注册的beanDefinition,不移除,并发会存在问题
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
		// 如果 beanDefinition 已经存在,且单例的bean已创建完成
		if (existingDefinition != null || containsSingleton(beanName)) {
			// 重新设置beanDefinition
			resetBeanDefinition(beanName);
		}
		else if (isConfigurationFrozen()) {
			clearByTypeCache();
		}
	}

其中在resetBeanDefinition中,存在函数销毁已创建的bean:destroySingleton,最终调用org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroyBean方法

	/**
	 * bean 及其相关信息被销毁后,在getBean时会重新解析beanDefinition 并重新生成
	 *
	 * Destroy the given bean. Must destroy beans that depend on the given
	 * bean before the bean itself. Should not throw any exceptions.
	 * @param beanName the name of the bean
	 * @param bean the bean instance to destroy
	 */
	protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
		// Trigger destruction of dependent beans first...
		Set<String> dependencies;
		// 删除依赖当前bean的bean
		synchronized (this.dependentBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			dependencies = this.dependentBeanMap.remove(beanName);
		}
		if (dependencies != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
			}
			for (String dependentBeanName : dependencies) {
				destroySingleton(dependentBeanName);
			}
		}

		// Actually destroy the bean now...
		if (bean != null) {
			try {
				bean.destroy();
			}
			catch (Throwable ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
				}
			}
		}

		// Trigger destruction of contained beans...
		Set<String> containedBeans;
		// 移除当前bean中包换的所有bean
		synchronized (this.containedBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			containedBeans = this.containedBeanMap.remove(beanName);
		}
		if (containedBeans != null) {
			for (String containedBeanName : containedBeans) {
				destroySingleton(containedBeanName);
			}
		}

		// Remove destroyed bean from other beans' dependencies.
		// 移除其他bean依赖当前bean的记录
		synchronized (this.dependentBeanMap) {
			for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
				Map.Entry<String, Set<String>> entry = it.next();
				Set<String> dependenciesToClean = entry.getValue();
				dependenciesToClean.remove(beanName);
				if (dependenciesToClean.isEmpty()) {
					it.remove();
				}
			}
		}

		// Remove destroyed bean's prepared dependency information.
		// 移除销毁bean的依赖信息
		this.dependenciesForBeanMap.remove(beanName);
	}

在看懂销毁一个bean是删除了哪些信息,其实间接的也就明白了初始化bean时都干了哪些事情

posted @ 2021-05-18 23:46  arax  阅读(88)  评论(0编辑  收藏  举报