基于Spring注解的上下文初始化过程源码解析(三)

2019-08-13 00:00:00 上下文 注解 初始化

上一篇跟完了 refresh 方法中第一个重要的方法 invokeBeanFactoryPostProcessors,

这篇继续分析 refresh 方法中第二个比较重要的 finishBeanFactoryInitialization 方法 

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	/**
	 * 初始化此上下文的转换服务
	 */
	if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
	}

	/**
	 * 如果之前没有注册 bean 后置处理器(例如 PropertyPlaceholderConfigurer)
	 * 则注册默认的嵌入值解析器:此时主要用于注释属性值的解析
	 */
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}
	// 获取 LoadTimeWeaverAware 的 BeanName 集合
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		// 初始化 LoadTimeWeaverAware 以允许尽早注册其变换器
		getBean(weaverAwareName);
	}

	// 停止使用临时 ClassLoader 进行类型匹配
	beanFactory.setTempClassLoader(null);

	// 允许缓存所有 BeanDefinition 元数据,不期望进一步更改
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
	// 实例化所有不是懒加载的单例对象
	beanFactory.preInstantiateSingletons();
} 

实例化所有非懒加载的单例对象方法中包含了 getBean 方法,先看  preInstantiateSingletons 方法

public void preInstantiateSingletons() throws BeansException {
	// 所有已注册的 BeanName 集合
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
	// 触发所有非延迟加载单例 Bean 的初始化,主要步骤为调用 getBean()方法
	for (String beanName : beanNames) {
		// 合并父 BeanDefinition
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 不是抽象类、是单例且不是懒加载的 Bean
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 判断该 Bean 是否是一个 FactoryBean
			if (isFactoryBean(beanName)) {
				/**
				 * 如果是 FactoryBean 则需要加上&才能实例化该 Bean
				 * 否则实例化的是该 FactoryBean 生产的对象
				 */
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				// 再次确认是 FactoryBean 的子类
				if (bean instanceof FactoryBean) {
					// 强转为父类
					final FactoryBean<?> factory = (FactoryBean<?>) bean;
					boolean isEagerInit;
					/**
					 * SecurityManager 不为空并且是 SmartFactoryBean 的子类
					 *
					 * SmartFactoryBean 的子类有 EagerInitFactory 和 NonPrivilegedFactoryBean
					 */
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						//
						isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
					} else {
						// 是 SmartFactoryBean 的子类并且是迫切需要被实例化的
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					// 如果是迫切需要被实例化的类,则实例化
					if (isEagerInit) {
						getBean(beanName);
					}
				}
			} else {
				// 实例化
				getBean(beanName);
			}
		}
	}
	// 触发所有适用 bean 的后初始化回调
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		/**
		 * 是 SmartInitializingSingleton 的子类
		 *
		 * EventListenerMethodProcessor 是 SmartInitializingSingleton 的子类
		 */
		if (singletonInstance instanceof SmartInitializingSingleton) {
			// 强转为 SmartInitializingSingleton
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			} else {
				// 回调 afterSingletonsInstantiated 方法
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}
getBean 方法是一个空壳方法,内部调用了 doGetBean 方法
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
		@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

	/**
	 * 通过 name 获取 BeanName。这里不使用 name 直接作为 BeanName 有两个原因:
	 *
	 *  1.name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 对象本身的实例,
	 * 	  而非 FactoryBean 实现类所创建的 Bean 对象实例。
	 *    在 BeanFactory 中,FactoryBean 的实现类和其他的 Bean 存储方式是一致的,
	 *    即<BeanName, BeanInstance>,BeanName中是没有 & 这个字符的,
	 *    所以需要将 name 的首字符 & 移除,这样才能从缓存里取到 FactoryBean 创建的实例
	 *  2.该 Bean 对象可能存在别名的问题
	 */
	// 解析 BeanName 为规范名称
	final String beanName = transformedBeanName(name);
	Object bean;

	/**
	 * 解决循环依赖问题【通过两次重载的 getSingleton() 方法和一次后置处理器方法的调用来解决循环依赖】
	 */

	// 第一次调用 getSingleton() 方法,检查单个缓存以手动注册单例。
	// 获取在给定名称下注册的(原始)单例对象。
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
		if (logger.isTraceEnabled()) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
				logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		// 获取给定 bean 实例的对象,如果是 FactoryBean,则为 bean 实例本身或其创建的对象。
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}
	// 已经创建过该实例对象
	else {
		// 如果已经创建了这个 bean 实例,则会失败:我们可以在循环引用中完成。
		// prototype 对象在每次 get 的时候创建,单例则不需要创建
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// 检查此工厂中是否存在 BeanDefinition
		BeanFactory parentBeanFactory = getParentBeanFactory();
		// 父工厂存在且不包含解析后的 beanName
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			String nameToLookup = originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				// 转换调用 doGetBean 方法
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				// 使用显式 args 委托父级
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else if (requiredType != null) {
				// 没有参数,委托标准的 getBean 方法
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
			else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}

		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}

		try {
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			// 校验是否是抽象的
			checkMergedBeanDefinition(mbd, beanName, args);

			// 初始化当前 Bean 依赖的 Bean【被 @DependsOn 注解指明需要依赖的 Bean】
			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dep : dependsOn) {
					// 校验是否是依赖项
					if (isDependent(beanName, dep)) {
						// 抛出循环依赖异常
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// 为给定 bean 注册依赖 bean
					registerDependentBean(dep, beanName);
					try {
						// 获取给定的 bean 实例
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						// 抛出依赖项缺失异常
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			// 创建 Bean 实例
			if (mbd.isSingleton()) {
				// 第二次调用,解决循环依赖问题
				sharedInstance = getSingleton(beanName, () -> {
					try {
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						destroySingleton(beanName);
						throw ex;
					}
				});
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

			else if (mbd.isPrototype()) {
				// 原型则创建新的实例
				Object prototypeInstance;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

			else {
				String scopeName = mbd.getScope();
				final Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						}
						finally {
								afterPrototypeCreation(beanName);
						}
					});
					bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName,
							"Scope '" + scopeName + "' is not active for the current thread; consider " +
							"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
							ex);
				}
			}
		}
		catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
	}

	// Check if required type matches the type of the actual bean instance.
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return convertedBean;
		}
		catch (TypeMismatchException ex) {
			if (logger.isTraceEnabled()) {
				logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
}  

 FactoryBean 是一种特殊的 Bean,能产生新的 Bean,获取的时候需要加’&’字符,否则获取的是其产生的 Bean。

Spring在这一步完成了所有非延迟加载的单例对象的初始化,至此 Spring 的 BeanFactory 就初始化完成了,分析的比较浅,也没有进行总结,后面会继续补充和完善,并辅以图表和示例代码。

相关文章