Spring 5 AbstractBeanFactory -- getBean() 源码分析(二)

58 篇文章 1 订阅
56 篇文章 3 订阅

Spring 5 AbstractBeanFactory – getBean() 源码分析(一)
Spring 5 AbstractBeanFactory – getBean() 源码分析(二)

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释

containsBeanDefinition(beanName)

该BeanFactory是否包含beanName的BeanDefinition对象。不考虑工厂可能参与的任何层次结构。
该方法在 AbstractBeanFactory 中是抽象方法

/**
	 * Check if this bean factory contains a bean definition with the given name.
	 * Does not consider any hierarchy this factory may participate in.
	 * Invoked by {@code containsBean} when no cached singleton instance is found.
	 * <p>该BeanFactory是否包含beanName的BeanDefinition对象。不考虑工厂可能参与的任何层次结构。
	 * 未找到缓存的单例实例时,由{@code containsBena}调用。</p>
	 * <p>Depending on the nature of the concrete bean factory implementation,
	 * this operation might be expensive (for example, because of directory lookups
	 * in external registries). However, for listable bean factories, this usually
	 * just amounts to a local hash lookup: The operation is therefore part of the
	 * public interface there. The same implementation can serve for both this
	 * template method and the public interface method in that case.
	 * <p>根据具体bean工厂实现的性质,此操作可能很昂贵(例如,由于在外部注册表中进行目录
	 * 寻找)。但是,对应可列出的bean工厂,这通常只相当于本地哈希查找:因此,该操作是该处
	 * 工厂接口的一部分。在这种情况下,该模板方法和公共接口方法都可以使用相同的实现。</p>
	 * @param beanName the name of the bean to look for - 要查找的bean名
	 * @return if this bean factory contains a bean definition with the given name
	 *  - 如果此bean工厂包含具有给定名称的bean定义。
	 * @see #containsBean
	 * @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition
	 */
	protected abstract boolean containsBeanDefinition(String beanName);

由 DefaultListableBeanFactory 实现:

/**
	 * Map of bean definition objects, keyed by bean name.
	 * <p>Bean定义对象的映射,以Bean名称为键</p>
	 * */
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
	
/**
	 * 本地工厂中BeanDefinition对象映射【beanDefinitionMap】中是否存在beanName该键名
	 * @param beanName the name of the bean to look for -- 要寻找的bean名
	 */
	@Override
	public boolean containsBeanDefinition(String beanName) {
		//如果beanName为null,抛出异常
		Assert.notNull(beanName, "Bean name must not be null");
		//从Beand定义对象映射中判断beanName是否存在该键
		return this.beanDefinitionMap.containsKey(beanName);
	}

originalBeanName(name)

获取name对应的规范名称【全类名/最终别名】,如果name前面有’&’,则会返回’&’+规范名称【全类名】

/**
	 * <p>获取name对应的规范名称【全类名/最终别名】,如果name前面有'&',则会返回'&'+规范名称【全类名】</p>
	 * Determine the original bean name, resolving locally defined aliases to canonical names.
	 * <p>确定原始bean名,将本地定义的别名解析为规范名称</p>
	 * @param name the user-specified name - 用户指定的名称
	 * @return the original bean name 原始bena名
	 */
	protected String originalBeanName(String name) {
		//获取name对应的规范名称【全类名】,包括以'&'开头的name
		String beanName = transformedBeanName(name);
		//如果name的开头有'&'
		if (name.startsWith(FACTORY_BEAN_PREFIX)) {
			//对beanName拼接上'&'在开头位置
			beanName = FACTORY_BEAN_PREFIX + beanName;
		}
		//返回规范的beanName
		return beanName;
	}

transformedBeanName(name);

去除name开头的’&‘字符,获取name最终的规范名称【最终别名或者是全类名】:去除开头的’&'字符,返回剩余的字符串得到转换后的Bean名称, 然后通过递归形式在 aliasMap【别名映射到规范名称集合】中得到最终的规范名称

/**
	 * Return the bean name, stripping out the factory dereference prefix if necessary,
	 * and resolving aliases to canonical names.
	 * <p>返回Bean名称,如果必要,去除工厂取消前缀,并将别名解析为规范名称</p>
	 * @param name the user-specified name - 用户指定的名称
	 * @return the transformed bean name - 转换后的bena名称
	 */
	protected String transformedBeanName(String name) {
		//去除开头的'&'字符,返回剩余的字符串得到转换后的Bean名称,然后通过递归形式在
		// aliasMap【别名映射到规范名称集合】中得到最终的规范名称
		return canonicalName(BeanFactoryUtils.transformedBeanName(name));
	}

BeanFactoryUtils.transformedBeanName(name)

去除开头的’&'字符,返回剩余的字符串作为转换后的Bean名称【可能是全类名】:

  1. 如果name为null,抛出异常
  2. 如果name不是以’&'开头,就直接返回
  3. 从具有FactoryBean前缀的名称缓存到剥离的名称的ConcurrentHashMap【transformedBenaNameCache】 中获取bean名对应的转换后的名称并返回
  4. 获取不到时就构建一个:从name的开头位置去掉’&’,再重新检查是否还是以’&‘开头,是的话就再截直到没有出现’&'开头为止。所得到 的字符串就是Bean名称【可能是全类名】
/**
	 * Return the actual bean name, stripping out the factory dereference
	 * prefix (if any, also stripping repeated factory prefixes if found).
	 * <p>返回实际的bean名称,删除工厂取消引用前缀(如果有的话,还删除重复的
	 * 工厂前缀(如果找到))</p>
	 * <p>用于获取以'&'开头的name对应的bean名,如果bean不是'&'开头,就直接返回该name</p>
	 * @param name the name of the bean - bean名
	 * @return the transformed name - 转换后的名称
	 * @see BeanFactory#FACTORY_BEAN_PREFIX
	 */
	public static String transformedBeanName(String name) {
		//如果bean名为null,抛出异常
		Assert.notNull(name, "'name' must not be null");
		//如果bean名不是以'&'开头,就直接返回
		if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
			return name;
		}
		//从transformedBenaNameCache中获取bean名对应的转换后的名称
		return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
			//从beanName的开头位置去掉'&',并重新赋值给beanName,再重新检查是还是以'&'开头,是的话就再截
			// 知道开头不是以'&'开头后,加入到transformedBeanNameCache中
			do {
				beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
			}
			while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
			return beanName;
		});
	}

markBeanAsCreated(beanName)

为指定的Bean标记为已经创建(或将要创建)

/**
	 * Names of beans that have already been created at least once.
	 * <p>至少已经创建一次的bean名称</p>
	 * */
	private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));

	/**
	 * Map from bean name to merged RootBeanDefinition.
	 * <p>从bean名称映射到合并的RootBeanDefinition</p>
	 * */
	private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);


	
/**
	 * Mark the specified bean as already created (or about to be created).
	 * 为指定的Bean标记为已经创建(或将要创建)
	 * <p>This allows the bean factory to optimize its caching for repeated
	 * creation of the specified bean.
	 * <p>这允许bean工厂优化其缓存,以便重复创建指定bean</p>
	 * @param beanName the name of the bean - bean名
	 */
	protected void markBeanAsCreated(String beanName) {
		//如果beanName还没有创建
		if (!this.alreadyCreated.contains(beanName)) {
			//同步,使用mergedBenDefinitions作为锁
			synchronized (this.mergedBeanDefinitions) {
				//如果beanName还没有创建
				if (!this.alreadyCreated.contains(beanName)) {
					// Let the bean definition get re-merged now that we're actually creating
					// the bean... just in case some of its metadata changed in the meantime.
					// 在我们实际创建时,重新合并bean定义。。以防万一期间的某些元数据发生了变化
					// 删除beanName合并bean定义,在下次访问时重新创建
					clearMergedBeanDefinition(beanName);
					this.alreadyCreated.add(beanName);
				}
			}
		}
	}

clearMergedBeanDefinition(beanName);

将beanName对应的合并后RootBeanDefinition对象标记为重新合并定义

/**
	 * <p>将beanName对应的合并后RootBeanDefinition对象标记为重新合并定义</p>
	 * Remove the merged bean definition for the specified bean,
	 * recreating it on next access.
	 * <p>删除指定的bean的合并bean定义,在下次访问时重新创建</p>
	 * <p>获取beanName合并后RootBeanDefinition对象【变量 bd】,将bd标记为需要重新合并定义【RootBeanDefinition#stale】/p>
	 * @param beanName the bean name to clear the merged definition for
	 *                 - bean名称以清除其合并定义
	 */
	protected void clearMergedBeanDefinition(String beanName) {
		//从合并后BeanDefinition集合缓存中获取beanName对应的合并后RootBeanDefinition对象
		RootBeanDefinition bd = this.mergedBeanDefinitions.get(beanName);
		//如果成功获取到了bd
		if (bd != null) {
			//将bd标记为需要重新合并定义
			bd.stale = true;
		}
	}

getMergedLocalBeanDefinition(beanName)

获取beanName合并后的本地RootBeanDefintiond

Spring 5 AbstractBeanFactory – getMergedLocalBeanDefinition 源码解析

checkMergedBeanDefinition(mbd, beanName, args);

检查给定的合并后mbd,不合格会引发验证异常:

  1. 如果mbd所配置的bean是抽象的就抛出异常
/**
	 * Check the given merged bean definition,
	 * potentially throwing validation exceptions.
	 * <p>检查给定的合并后mbd,不合格会引发验证异常
 </p>
	 * @param mbd the merged bean definition to check -- 要检查的合并后RootBeanDefinition
	 * @param beanName the name of the bean -- bean名
	 * @param args the arguments for bean creation, if any -- 创建bean的参数(如果有)
	 * @throws BeanDefinitionStoreException in case of validation failure -- 如果验证失败
	 */
	protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
			throws BeanDefinitionStoreException {
		//如果mbd所配置的bean是抽象的
		if (mbd.isAbstract()) {
			//抛出Bean为抽象异常
			throw new BeanIsAbstractException(beanName);
		}
	}

isDependent(beanName, dep)

判断beanName是否已注册依赖于dependentBeanName的关系
由 DefaultSingletonBeanRegistry 实现

/**
	 * <p>存储 bean名到该bean名所要依赖的bean名 的Map,不理解的请看 {@link #registerDependentBean(String, String)}</p>
	 * Map between dependent bean names: bean name to Set of dependent bean names.
	 * <p>在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称</p>
	 * */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

/**
	 * Determine whether the specified dependent bean has been registered as
	 * dependent on the given bean or on any of its transitive dependencies.
	 * <p>确定指定的依赖bean是否已注册为依赖于给定bean或其任何传递依赖</p>
	 * @see #isDependent(String, String, Set)
	 * @param beanName the name of the bean to check -- 要检查的bean名
	 * @param dependentBeanName the name of the dependent bean -- 依赖名称
	 * @since 4.0
	 */
	protected boolean isDependent(String beanName, String dependentBeanName) {
		//使用依赖bean关系Map作为锁,保证线程安全
		synchronized (this.dependentBeanMap) {
			return isDependent(beanName, dependentBeanName, null);
		}
	}

registerDependentBean(dep, beanName)

注册beanName与dependentBeanNamed的依赖关系:

  1. 获取name的最终别名或者是全类名 【变量 canonicalName】
  2. 注册到存储 bean名到该bean名所要依赖的bean名 的Map【dependentBeanMap】:
    1. 使用dependentBeanMap作为锁,保证线程安全
    2. 获取canonicalName对应的用于存储依赖Bean名的Set集合,如果没有就创建一个LinkeHashSet,并与canonicalName绑定到dependentBeans中
    3. 如果dependendBeans已经添加过来了dependentBeanName,就结束该方法,不执行后面操作。
  3. 注册到 存储 bean名到依赖于该bean名的bean名 的Map【dependenciesForBeanMap】:
    1. 使用Bean依赖关系Map作为锁,保证线程安全
    2. 添加dependendtBeanName依赖于cannoicalName的映射关系到dependenciesForBeanMap中
/**
	 * Register a dependent bean for the given bean,
	 * to be destroyed before the given bean is destroyed.
	 * <p>为给定的bean注册一个从属bean,要在给定的bean被销毁之前将其销毁。</p>
	 * @param beanName the name of the bean -- bean名
	 * @param dependentBeanName the name of the dependent bean -- 依赖bean名
	 */
	public void registerDependentBean(String beanName, String dependentBeanName) {
		//获取name的最终别名或者是全类名
		String canonicalName = canonicalName(beanName);
		//使用 存储 bean名到该bean名所要依赖的bean名 的Map 作为锁,保证线程安全
		synchronized (this.dependentBeanMap) {
			//获取canonicalName对应的用于存储依赖Bean名的Set集合,如果没有就创建一个LinkeHashSet,并与canonicalName绑定到dependentBeans中
			Set<String> dependentBeans =
					this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
			//如果dependendBeans已经添加过来了dependentBeanName,就结束该方法,不执行后面操作。
			if (!dependentBeans.add(dependentBeanName)) {
				return;
			}
		}

		//使用Bean依赖关系Map作为锁,保证线程安全
		synchronized (this.dependenciesForBeanMap) {
			//添加dependendtBeanName依赖于cannoicalName的映射关系到 存储 bean名到依赖于该bean名的bean名 的Map中
			Set<String> dependenciesForBean =
					this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
			dependenciesForBean.add(canonicalName);
		}
	}

canonicalName(beanName)

获取name的最终别名或者是全类名
1. 通过递归形式在aliasMap【别名映射到规范名称集合】中得到最终的规范名称
由 SimpleAliasRegistry 实现

/**
	 * Map from alias to canonical name.
	 * <p>从别名映射到规范名称</p>
	 * <p>整个Map数据结构应该要抽象理解为一个二维数组,因为在检索别名的时候,是可以通过别名查别名的。</p>
	 * <p>举个栗子:
	 *  <ol>
	 *   <li>A是B的别名,C是B的别名,存放到aliasMap中的数据结构就是:[{key=B,val=A},{key=C,val=B}]</li>
	 *   <li>当要获取A的所有别名[B,C]时:先获取A的Key->B,则通过递归形式获取B的key->C。</li>
	 *  </ol>
	 * </p>
	 * */
	private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
	
/**
	 * Determine the raw name, resolving aliases to canonical names.
	 * <p>确定原始名称,将别名解析为规范名称</p>
	 * @param name the user-specified name - 用户指定的名称
	 * @return the transformed name - 转换后的名称
	 */
	public String canonicalName(String name) {
		//规范名称初始化化传入的name
		String canonicalName = name;
		// Handle aliasing... 处理别名
		String resolvedName;
		//从下面代码可以看出,aliasMap的存储形式是:
		// C是真正的规范名称,A,B都是别名:
		// 		aliasMap={key:A,val:B;key:B,val:C},通过A拿到B,再通过B拿到C
		do {
			//通过 规范名称 从 aliasMap中获取解析后的名称
			resolvedName = this.aliasMap.get(canonicalName);
			//如果找到了解析后的名称
			if (resolvedName != null) {
				//规范名称重新赋值为解析后名称
				canonicalName = resolvedName;
			}
		}
		//只要找到了解析后的名称
		while (resolvedName != null);
		return canonicalName;
	}

getSingleton(beanName, singletonFactory)

返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:

Spring 5 DefaultSingletonBeanRegistry – getSingleton(String,ObjectFactory) 源码解析

createBean(beanName, mbd, args);

为给定的合并后BeanDefinition(和参数)创建一个bean实例

Spring 5 AbstractBeanFactory – createBean 源码解析(一)
Spring 5 AbstractBeanFactory – createBean 源码解析(二)

destroySingleton(beanName);

销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
由 DefaultSingletonBeanRegistry 实现


/**
	 * Disposable bean instances: bean name to disposable instance.
	 * <p>一次性Bean实例:bean名称 - DisposableBean实例。</p>
	 * */
	private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
	
/**
	 * Destroy the given bean. Delegates to {@code destroyBean}
	 * if a corresponding disposable bean instance is found.
	 * <p>销毁给定的bean。如果找到相应的一次性Bean实例,则委托给{@code destoryBean}</p>
	 * @param beanName the name of the bean -- bean名
	 * @see #destroyBean
	 */
	public void destroySingleton(String beanName) {
		// Remove a registered singleton of the given name, if any.
		// 删除给定名称的已注册的单例(如果有)
		removeSingleton(beanName);

		// Destroy the corresponding DisposableBean instance.
		// 销毁相应的DisposableBean实例
		// DisposableBean:要在销毁时释放资源的bean所实现的接口.包括已注册为一次性的内部bean。
		// 	在工厂关闭时调用。
		DisposableBean disposableBean;
		//同步,将 一次性Bean实例:bean名称 -  DisposableBean实例 作为锁
		synchronized (this.disposableBeans) {
			//从disposableBeans移除出disposableBean对象
			disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
		}
		//销毁给定bean。必须先销毁依赖于给定bean的bean。然后再销毁bean。
		destroyBean(beanName, disposableBean);
	}

removeSingleton(beanName);

从该工厂单例缓存中删除具有给定名称的Bean。如果创建失败,则能够清理饿汉式注册 的单例

/**
	 * Cache of singleton objects: bean name to bean instance.
	 * <p>单例对象的高速缓存:beam名称-bean实例,所有bean对象最终都会放到对象中</p>
	 * */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/**
	 * Cache of singleton factories: bean name to ObjectFactory.
	 * <p>单例工厂的缓存:bean名称 - ObjectFactory </p>
	 * */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/**
	 * Cache of early singleton objects: bean name to bean instance.
	 * <p>早期单例对象的高速缓存:bean名称 - bean实例</p>
	 * <p>当从singletonFactories中获取到对应对象后,就会放到这个缓存中</p>
	 * */
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

	/**
	 * Set of registered singletons, containing the bean names in registration order.
	 * <p>已注册的单例集,按照注册顺序包含bean名称</p>
	 * <p>用于保证工厂内的beanName是唯一的</p>
	 * */
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
	
	/**
	 * Remove the bean with the given name from the singleton cache of this factory,
	 * to be able to clean up eager registration of a singleton if creation failed.
	 * <p>从该工厂单例缓存中删除具有给定名称的Bean。如果创建失败,则能够清理饿汉式注册
	 * 的单例</p>
	 * @param beanName the name of the bean -- bean名
	 * @see #getSingletonMutex()
	 */
	protected void removeSingleton(String beanName) {
		//同步,使用 单例对象的高速缓存:beam名称-bean实例 作为锁
		synchronized (this.singletonObjects) {
			//删除 单例对象的高速缓存:beam名称-bean实例 的对应数据
			this.singletonObjects.remove(beanName);
			//删除 单例工厂的缓存:bean名称 - ObjectFactory 的对应数据
			this.singletonFactories.remove(beanName);
			//删除 单例对象的高速缓存:beam名称-bean实例 的对应数据
			this.earlySingletonObjects.remove(beanName);
			//删除 已注册的单例集,按照注册顺序包含bean名称 的对应数据
			this.registeredSingletons.remove(beanName);
		}
	}

destroyBean(beanName, disposableBean);

	
	/**
	 * <p>存储 bean名到该bean名所要依赖的bean名 的Map,不理解的请看 {@link #registerDependentBean(String, String)}</p>
	 * Map between dependent bean names: bean name to Set of dependent bean names.
	 * <p>在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称</p>
	 * */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

	/**
	 * <p>存储 bean名到依赖于该bean名的bean名 的Map,不理解的请看 {@link #registerDependentBean(String, String)}<</p>
	 *  Map between depending bean names: bean name to Set of bean names for the bean's dependencies.
	 * <p>在相关的Bean名称之j键映射:bean名称 bean依赖项的Bean名称集</p>
	 * */
	private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

/**
	 * Destroy the given bean. Must destroy beans that depend on the given
	 * bean before the bean itself. Should not throw any exceptions.
	 * <p>销毁给定bean。必须先销毁依赖于给定bean的bean。然后再销毁bean。
	 * 不应抛出任何异常</p>
	 * @param beanName the name of the bean --  bean名
	 * @param bean the bean instance to destroy -- 要销毁的bean实例
	 */
	protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
		// Trigger destruction of dependent beans first...
		// 先触发从依赖的bean的破坏
		Set<String> dependencies;
		//同步,使用 在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称 作为锁
		synchronized (this.dependentBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			// 在完全同步内以确保断开连续集
			//从dependentBeanMap中移除出beanName对应的依赖beanName集
			dependencies = this.dependentBeanMap.remove(beanName);
		}
		//如果存在依赖的beanName集
		if (dependencies != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
			}
			//遍历依赖的BeanName
			for (String dependentBeanName : dependencies) {
				递归删除dependentBeanName的实例
				destroySingleton(dependentBeanName);
			}
		}

		// Actually destroy the bean now... 实现上现在销毁的bean
		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... 触发销毁所包含的bean
		Set<String> containedBeans;
		//同步,使用 在包含的Bean名称之间映射:bean名称 - Bean包含的Bean名称集 作为锁
		synchronized (this.containedBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			containedBeans = this.containedBeanMap.remove(beanName);
		}
		//如果存在BeanName包含的bean名称集
		if (containedBeans != null) {
			//遍历BeanName包含的bean名称集
			for (String containedBeanName : containedBeans) {
				//递归删除containedBeanName的实例
				destroySingleton(containedBeanName);
			}
		}

		// Remove destroyed bean from other beans' dependencies.
		// 从其他bean的依赖项中删除破坏的bean
		//同步,在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称 作为锁
		synchronized (this.dependentBeanMap) {
			//遍历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();
				//从其它bean的依赖bean集合中移除beanName
				dependenciesToClean.remove(beanName);
				//如果依赖bean集合没有任何元素了
				if (dependenciesToClean.isEmpty()) {
					//将整个映射关系都删除
					it.remove();
				}
			}
		}

		// Remove destroyed bean's prepared dependency information.
		// 删除销毁的bean准备的依赖的依赖项信息
		// 从 在相关的Bean名称之键映射:bean名称 bean依赖项的Bean名称集 删除beanName的映射关系
		this.dependenciesForBeanMap.remove(beanName);
	}

destroySingleton(dependentBeanName);

销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
由 DefaultSingletonBeanRegistry 实现。

/**
	 * Disposable bean instances: bean name to disposable instance.
	 * <p>一次性Bean实例:bean名称 - DisposableBean实例。</p>
	 * */
	private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
	
	/**
	 * Destroy the given bean. Delegates to {@code destroyBean}
	 * if a corresponding disposable bean instance is found.
	 * <p>销毁给定的bean。如果找到相应的一次性Bean实例,则委托给{@code destoryBean}</p>
	 * @param beanName the name of the bean -- bean名
	 * @see #destroyBean
	 */
	public void destroySingleton(String beanName) {
		// Remove a registered singleton of the given name, if any.
		// 删除给定名称的已注册的单例(如果有)
		removeSingleton(beanName);

		// Destroy the corresponding DisposableBean instance.
		// 销毁相应的DisposableBean实例
		// DisposableBean:要在销毁时释放资源的bean所实现的接口.包括已注册为一次性的内部bean。
		// 	在工厂关闭时调用。
		DisposableBean disposableBean;
		//同步,将 一次性Bean实例:bean名称 -  DisposableBean实例 作为锁
		synchronized (this.disposableBeans) {
			//从disposableBeans移除出disposableBean对象
			disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
		}
		//销毁给定bean。必须先销毁依赖于给定bean的bean。然后再销毁bean。
		destroyBean(beanName, disposableBean);
	}

getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

从 beanInstannce 中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是FactoryBean会直接 返回beanInstance实例

/**
	 * <p>从 beanInstannce 中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是FactoryBean会直接
	 * 返回beanInstance实例</p>
	 * Get the object for the given bean instance, either the bean
	 * instance itself or its created object in case of a FactoryBean.
	 * <p>获取给定Bean实例对象,对于FactoryBean,可以是Bean实例本身,也可以
	 * 是它创建的对象</p>
	 * @param beanInstance the shared bean instance - 共享bean实例
	 * @param name name that may include factory dereference prefix - 可能包含工厂取消引用前缀的名字
	 * @param beanName the canonical bean name - 规范bean名
	 * @param mbd the merged bean definition - 合并的bean定义
	 * @return the object to expose for the bean - 为bean公开的对象
	 */
	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// Don't let calling code try to dereference the factory if the bean isn't a factory.
		// 如果Bean不是工厂,不要让调用代码尝试取消对工厂的引用
		// 如果 name为FactoryBean的解引用.name是以'&'开头,就是FactoryBean的解引用
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			//如果beanInstance是NullBean实例
			if (beanInstance instanceof NullBean) {
				//返回beanInstance
				return beanInstance;
			}
			//如果beanInstance不是FactoryBean实例
			if (!(beanInstance instanceof FactoryBean)) {
				//抛出Bean不是一个Factory异常
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			//如果mbd不为null
			if (mbd != null) {
				//设置mbd是否是FactoryBean标记为true
				mbd.isFactoryBean = true;
			}
			//返回beanInstance
			return beanInstance;
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		// 现在我们有了Bean实例,他可能是一个普通的Bean或FactoryBean。
		// 如果它是FactoryBean,我们使用它来创建一个Bean实例,除非调用者确实需要对工厂的引用。
		//如果beanInstance不是FactoryBean实例
		if (!(beanInstance instanceof FactoryBean)) {
			return beanInstance;
		}
		//定义为bean公开的对象,初始化为null
		Object object = null;
		//如果mbd不为null
		if (mbd != null) {
			//更新mbd的是否是FactoryBean标记为true
			mbd.isFactoryBean = true;
		}
		else {
			//从FactoryBean获得的对象缓存集中获取beanName对应的Bean对象
			object = getCachedObjectForFactoryBean(beanName);
		}
		//如果object为null
		if (object == null) {
			// Return bean instance from factory.
			// 从工厂返回Bean实例
			//将beanInstance强转为FactoryBean对象
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			// 如果是单例对象,则缓存从FactoryBean获得的对象、
			//如果mbd为null && 该BeanFactory包含beanName的BeanDefinition对象。
			if (mbd == null && containsBeanDefinition(beanName)) {
				//获取beanName合并后的本地RootBeanDefintiond对象
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			//是否是'synthetic'标记:mbd不为null && 返回此bean定义是否是"synthetic"【一般是指只有AOP相关的prointCut配置或者
			// 		Advice配置才会将 synthetic设置为true】
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//从BeanFactory对象中获取管理的对象.如果不是synthetic会对其对象进行该工厂的后置处理
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		//返回为bean公开的对象
		return object;
	}

getObjectFromFactoryBean(factory, beanName, !synthetic);

Spring 5 AbstractBeanFactory – getObjectFromFactoryBean 源码解析

beforePrototypeCreation(beanName);

创建ProtoPype对象前的准备工作,默认实现 将beanName添加到 prototypesCurrentlyInCreation 中


/**
	 * Names of beans that are currently in creation.
	 * <p>当前正在创建的bean名称</p>
	 * */
	private final ThreadLocal<Object> prototypesCurrentlyInCreation =
			new NamedThreadLocal<>("Prototype beans currently in creation");
			
/**
	 * <p>创建ProtoPype对象前的准备工作,默认实现 将beanName添加到 prototypesCurrentlyInCreation 中</p>
	 * Callback before prototype creation.
	 * <p>原型创建前的回调</p>
	 * <p>The default implementation register the prototype as currently in creation.
	 * <p>默认实现将原型注册为当前创建中</p>
	 * @param beanName the name of the prototype about to be created
	 *                 -- 将要创建的原型的名称
	 * @see #isPrototypeCurrentlyInCreation
	 */
	@SuppressWarnings("unchecked")
	protected void beforePrototypeCreation(String beanName) {
		//prototypesCurrentlyInCreation:当前正在创建的bean名称
		//从 prototypesCurrentlyInCreation中获取线程安全的当前正在创建的Bean对象名
		Object curVal = this.prototypesCurrentlyInCreation.get();
		//如果curlVal为null
		if (curVal == null) {
			//将beanName设置到propertysCurrentlyInCreation中
			this.prototypesCurrentlyInCreation.set(beanName);
		}
		//如果curlValue是Stringl类型
		else if (curVal instanceof String) {
			//定义一个HashSet对象存放prototypesCurrentlyInCreation原有Bean名 和 beanName
			Set<String> beanNameSet = new HashSet<>(2);
			//将curlVal添加beanNameSet中
			beanNameSet.add((String) curVal);
			//将beanName添加到beanNameSet中
			beanNameSet.add(beanName);
			//将beanNameSet设置到propertysCurrentlyInCreation中
			this.prototypesCurrentlyInCreation.set(beanNameSet);
		}
		else {
			//否则,curlValue就只会是HashSet对象
			//将curlVal强转为Set对象
			Set<String> beanNameSet = (Set<String>) curVal;
			//将beanName添加到beanNameSet中
			beanNameSet.add(beanName);
		}
	}

afterPrototypeCreation(beanName);

创建完prototype实例后的回调,默认是将beanName从 prototypesCurrentlyInCreation 移除

/**
	 * Names of beans that are currently in creation.
	 * <p>当前正在创建的bean名称</p>
	 * */
	private final ThreadLocal<Object> prototypesCurrentlyInCreation =
			new NamedThreadLocal<>("Prototype beans currently in creation");
			
/**
	 * <p>创建完prototype实例后的回调,默认是将beanName从 prototypesCurrentlyInCreation 移除</p>
	 * Callback after prototype creation.
	 * <p>原型创建后的回调</p>
	 * <p>The default implementation marks the prototype as not in creation anymore.
	 * <p>默认实现将原型标记为不在创建中</p>
	 * @param beanName the name of the prototype that has been created
	 *                 -- 已创建的原型的名称
	 * @see #isPrototypeCurrentlyInCreation
	 */
	@SuppressWarnings("unchecked")
	protected void afterPrototypeCreation(String beanName) {
		//从prototypesCurrentlyInCreation获取当前正在创建的Bean名
		Object curVal = this.prototypesCurrentlyInCreation.get();
		//将curlVal是String对象
		if (curVal instanceof String) {
			//将curlVal从prototypesCurrentlyInCreation中移除
			this.prototypesCurrentlyInCreation.remove();
		}
		//如果curlVal是Set对象
		else if (curVal instanceof Set) {
			//将curValue强转为Set对象
			Set<String> beanNameSet = (Set<String>) curVal;
			//将beanName从beanNameSet中移除
			beanNameSet.remove(beanName);
			//如果beanNameSet已经没有元素了
			if (beanNameSet.isEmpty()) {
				//将beanNameSet从prototypesCurrentlyInCreation中移除
				this.prototypesCurrentlyInCreation.remove();
			}
		}
	}

cleanupAfterBeanCreationFailure(beanName);

在Bean创建失败后,对缓存的元数据执行适当的清理

/**
	 * Map from bean name to merged RootBeanDefinition.
	 * <p>从bean名称映射到合并的RootBeanDefinition</p>
	 * */
	private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);

	/**
	 * Names of beans that have already been created at least once.
	 * <p>至少已经创建一次的bean名称</p>
	 * */
	private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
	
	/**
	 * Perform appropriate cleanup of cached metadata after bean creation failed.
	 * <p>在Bean创建失败后,对缓存的元数据执行适当的清理</p>
	 * @param beanName the name of the bean -- bean名
	 */
	protected void cleanupAfterBeanCreationFailure(String beanName) {
		//mergedBeanDefinitions:从bean名称映射到合并的RootBeanDefinition
		//使用mergedBeanDefinitions加锁,保证线程安全
		synchronized (this.mergedBeanDefinitions) {
			//alreadyCreated:至少已经创建一次的bean名称
			//将beanName从alreadyCreated中删除
			this.alreadyCreated.remove(beanName);
		}
	}

TypeConverter

Spring 5 SimpleTypeConverter 源码注释

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引入一个依赖后,启动springboot报错:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultValidator' defined in class path resource [org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.AbstractMethodError: org.hibernate.validator.engine.ConfigurationImpl.getDefaultParameterNameProvider()Ljavax/validation/ParameterNameProvider; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:893) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
最新发布
06-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值