3

Spring Ioc源码分析系列--Bean实例化过程(二) - Codegitz

 1 year ago
source link: https://www.cnblogs.com/codegitz/p/16331774.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Spring Ioc源码分析系列--Bean实例化过程(二)

上篇文章Spring Ioc源码分析系列--Bean实例化过程(一)简单分析了getBean()方法,还记得分析了什么吗?不记得了才是正常的,记住了才是怪人,忘记了可以回去翻翻,翻不翻都没事, 反正最后都会忘了。

这篇文章是给上篇填坑的,上篇分析到真正创建Bean的createBean(beanName, mbd, args)就没有继续深入去分析了,绕得太深,说不清楚。那么这一篇,就续上这个口子,去分析createBean(beanName, mbd, args)方法。

话不多说,我们直接来到createBean(beanName, mbd, args)方法的源码。具体的实现是在AbstractAutowireCapableBeanFactory#createBean(beanName, mbd, args)里,可以直接定位到这里。

createBean()方法

跟进代码查看,这个方法也比较简单,主要分为了以下几点:

  • 初始化化Class对象。调用resolveBeanClass(mbd, beanName)方法获取class对象,这里会去解析类全限定名,最终是通过反射方法Class<?> resolvedClass = ClassUtils.forName(className, classLoader)获取Class对象。
  • 检查覆盖方法。对应的是mbdToUse.prepareMethodOverrides()方法,这里会对一些重载方法进行标记预处理,如果同方法名的方法只存在一个,那么会将覆盖标记为未重载,以避免 arg 类型检查的开销。
  • 应用后置处理器。在实例化对象前,会经过后置处理器处理,这个后置处理器的提供了一个短路机制,就是可以提前结束整个Bean的生命周期,直接从这里返回一个Bean。
  • 创建Bean。调用doCreateBean()方法进行Bean的创建,在Spring里面,带有do开头的一般是真正干活的方法,所以Ioc创建Bean到这里,才是真正要到干活的地方了。

我们庖丁解牛先把方法不同的功能按照逻辑拆分了,那接下来,就详细分析一下每个部分。

	/**
	 * Central method of this class: creates a bean instance,
	 * populates the bean instance, applies post-processors, etc.
	 *
	 * 此类的中心方法:创建 bean 实例、填充 bean 实例、应用后处理器等。
	 *
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		//锁定class ,根据设置的 class 属性或者根据 className 来解析 Class
		// 解析得到beanClass,为什么需要解析呢?如果是从XML中解析出来的标签属性肯定是个字符串嘛
		// 所以这里需要加载类,得到Class对象
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.验证及准备覆盖的方法
		// 对XML标签中定义的lookUp属性进行预处理,
		// 如果只能根据名字找到一个就标记为非重载的,这样在后续就不需要去推断到底是哪个方法了,
		// 对于@LookUp注解标注的方法是不需要在这里处理的,
		// AutowiredAnnotationBeanPostProcessor会处理这个注解
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			//给BeanPostProcessors一个露脸的机会
			// 在实例化对象前,会经过后置处理器处理
			// 这个后置处理器的提供了一个短路机制,就是可以提前结束整个Bean的生命周期,直接从这里返回一个Bean
			// 不过我们一般不会这么做,它的另外一个作用就是对AOP提供了支持,
			// 在这里会将一些不需要被代理的Bean进行标记,就本IoC系列文章而言,你可以暂时理解它没有起到任何作用
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			//若果有自定义bean则直接返回了bean,不会再走后续的doCreateBean方法
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			// 不存在提前初始化的操作,开始正常的创建流程
			// doXXX方法,真正干活的方法,doCreateBean,真正创建Bean的方法
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// 省略部分异常..
		}
		}
	}

初始化Class对象

很显然初始化Class对象的代码在resolveBeanClass(mbd, beanName)方法里,跟进代码查看。

	/**
	 * Resolve the bean class for the specified bean definition,
	 * resolving a bean class name into a Class reference (if necessary)
	 * and storing the resolved Class in the bean definition for further use.
	 *
	 * 为指定的 bean 定义解析 bean 类,将 bean 类名称解析为 Class 引用(如果需要)并将解析的 Class 存储在 bean 定义中以供进一步使用。
	 *
	 * @param mbd the merged bean definition to determine the class for
	 * @param beanName the name of the bean (for error handling purposes)
	 * @param typesToMatch the types to match in case of internal type matching purposes
	 * (also signals that the returned {@code Class} will never be exposed to application code)
	 *       在内部类型匹配的情况下要匹配的类型(也表示返回的 {@code Class} 永远不会暴露给应用程序代码)
	 * @return the resolved bean class (or {@code null} if none)
	 * @throws CannotLoadBeanClassException if we failed to load the class
	 */
	@Nullable
	protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
			throws CannotLoadBeanClassException {

		try {
			// 如果已经创建过,直接返回
			if (mbd.hasBeanClass()) {
				return mbd.getBeanClass();
			}
			if (System.getSecurityManager() != null) {
				return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
					doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
			}
			else {
				// 否则进行创建
				return doResolveBeanClass(mbd, typesToMatch);
			}
		}
		catch (PrivilegedActionException pae) {
			// 省略部分异常处理
		}
	}

跟进doResolveBeanClass(mbd, typesToMatch)方法,我们这里传入的typesToMatch参数对象数组为空,所以不会走排除部分类的逻辑,接下来是使用evaluateBeanDefinitionString()方法计算表达式如果传入的className有占位符,会在这里被解析,最终正常我们会走到mbd.resolveBeanClass(beanClassLoader)方法里。

	private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
			throws ClassNotFoundException {

		// 获取类加载器
		ClassLoader beanClassLoader = getBeanClassLoader();
		ClassLoader dynamicLoader = beanClassLoader;
		boolean freshResolve = false;

		if (!ObjectUtils.isEmpty(typesToMatch)) {
			// When just doing type checks (i.e. not creating an actual instance yet),
			// use the specified temporary class loader (e.g. in a weaving scenario).
			// 当只是进行类型检查(即尚未创建实际实例)时,请使用指定的临时类加载器(例如在编织场景中)。
			ClassLoader tempClassLoader = getTempClassLoader();
			if (tempClassLoader != null) {
				dynamicLoader = tempClassLoader;
				freshResolve = true;
				if (tempClassLoader instanceof DecoratingClassLoader) {
					DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
					for (Class<?> typeToMatch : typesToMatch) {
						dcl.excludeClass(typeToMatch.getName());
					}
				}
			}
		}

		String className = mbd.getBeanClassName();
		if (className != null) {
			Object evaluated = evaluateBeanDefinitionString(className, mbd);
			if (!className.equals(evaluated)) {
				// A dynamically resolved expression, supported as of 4.2...
				if (evaluated instanceof Class) {
					return (Class<?>) evaluated;
				}
				else if (evaluated instanceof String) {
					className = (String) evaluated;
					freshResolve = true;
				}
				else {
					throw new IllegalStateException("Invalid class name expression result: " + evaluated);
				}
			}
			if (freshResolve) {
				// When resolving against a temporary class loader, exit early in order
				// to avoid storing the resolved Class in the bean definition.
				// 当针对临时类加载器解析时,请提前退出以避免将解析的类存储在 bean 定义中。
				if (dynamicLoader != null) {
					try {
						// 使用临时动态加载器加载 class 对象
						return dynamicLoader.loadClass(className);
					}
					catch (ClassNotFoundException ex) {
						if (logger.isTraceEnabled()) {
							logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
						}
					}
				}
				// 反射加载 class 对象
				return ClassUtils.forName(className, dynamicLoader);
			}
		}

		// Resolve regularly, caching the result in the BeanDefinition...
		// 正常解析,将结果缓存在 BeanDefinition...
		return mbd.resolveBeanClass(beanClassLoader);
	}

跟进mbd.resolveBeanClass(beanClassLoader)方法,可以看到这里就是使用反射初始化Class对象,然后缓存在BeanDefinition中。到这里,已经完成了从一个字符串的类名到一个Class对象的转换了,我们已经得到了一个可以使用的Class对象。

	/**
	 * Determine the class of the wrapped bean, resolving it from a
	 * specified class name if necessary. Will also reload a specified
	 * Class from its name when called with the bean class already resolved.
	 *
	 * 确定被包装的 bean 的类,必要时从指定的类名解析它。当使用已解析的 bean 类调用时,还将从其名称中重新加载指定的类。
	 *
	 * @param classLoader the ClassLoader to use for resolving a (potential) class name
	 * @return the resolved bean class
	 * @throws ClassNotFoundException if the class name could be resolved
	 */
	@Nullable
	public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
		String className = getBeanClassName();
		if (className == null) {
			return null;
		}
		Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
		this.beanClass = resolvedClass;
		return resolvedClass;
	}

检查覆盖方法

初始化class对象已经完成了,接下来会去处理重载方法,处理的逻辑在mbdToUse.prepareMethodOverrides()方法里。

摘取《Spring源码深度解析》里面的一段话:

很多读者可能会不知道这个方法的作用,因为在 Spring 的配置里面根本就没有诸如 override-method 之类的配置, 那么这个方法到底是干什么用的呢? 其实在 Spring 中确实没有 override-method 这样的配置,但是在 Spring 配置中是存在 lookup-methodreplace-method 的,而这两个配置的加载其实就是将配置统一存放在 BeanDefinition 中的 methodOverrides 属性里,而这个函数的操作其实也就是针对于这两个配置的。

lookup-method通常称为获取器注入,spring in action 中对它的描述是,一种特殊的方法注入,它是把一个方法声明为返回某种类型的 bean,而实际要返回的 bean 是在配置文件里面配置的,可用在设计可插拔的功能上,解除程序依赖。 这里会对一些重载方法进行标记预处理,如果同方法名的方法只存在一个,那么会将覆盖标记为未重载,以避免 arg 类型检查的开销。

这种骚操作我们基本是不会使用的,所以简单看一下代码,浅尝辄止,有兴趣可以去翻翻。

	/**
	 * Validate and prepare the method overrides defined for this bean.
	 * Checks for existence of a method with the specified name.
	 *
	 * 验证并准备为此 bean 定义的方法覆盖。检查具有指定名称的方法是否存在。
	 *
	 * @throws BeanDefinitionValidationException in case of validation failure
	 */
	public void prepareMethodOverrides() throws BeanDefinitionValidationException {
		// Check that lookup methods exist and determine their overloaded status.
		// 检查查找方法是否存在并确定它们的重载状态。
		if (hasMethodOverrides()) {
			getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
		}
	}

可以看到这里就获取所有methodOverrides,然后遍历去调用prepareMethodOverride()方法,跟进prepareMethodOverride()方法。可以看到这里就是做个简单的标记。

	/**
	 * Validate and prepare the given method override.
	 * Checks for existence of a method with the specified name,
	 * marking it as not overloaded if none found.
	 *
	 * 验证并准备给定的方法覆盖。检查具有指定名称的方法是否存在,如果没有找到,则将其标记为未重载。
	 *
	 * @param mo the MethodOverride object to validate
	 * @throws BeanDefinitionValidationException in case of validation failure
	 */
	protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
		int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
		if (count == 0) {
			throw new BeanDefinitionValidationException(
					"Invalid method override: no method with name '" + mo.getMethodName() +
					"' on class [" + getBeanClassName() + "]");
		}
		else if (count == 1) {
			// Mark override as not overloaded, to avoid the overhead of arg type checking.
			// 将覆盖标记为未重载,以避免 arg 类型检查的开销。
			mo.setOverloaded(false);
		}
	}

应用后置处理器

在实例化对象前,会经过后置处理器处理,这个后置处理器的提供了一个短路机制,就是可以提前结束整个Bean的生命周期,直接从这里返回一个Bean。不过我们一般不会这么做,它的另外一个作用就是对AOP提供了支持,在这里会将一些不需要被代理的Bean进行标记,就本IoC系列文章而言,你可以暂时理解它没有起到任何作用。

跟进代码resolveBeforeInstantiation(beanName, mbdToUse)查看。

	/**
	 * Apply before-instantiation post-processors, resolving whether there is a
	 * before-instantiation shortcut for the specified bean.
	 *
	 * 应用实例化前后处理器,解析指定 bean 是否存在实例化前快捷方式。
	 * 实例化前的快捷方式的意思这里可能会直接返回一个定义的代理,而不需要在把目标类初始化
	 *
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return the shortcut-determined bean instance, or {@code null} if none
	 */
	//注意单词Instantiation和Initialization区别
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				// 确定给定的 bean 的类型
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					// 提供一个提前初始化的时机,这里会直接返回一个实例对象
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						// 如果提前初始化成功,则执行 postProcessAfterInitialization() 方法,注意单词Instantiation和Initialization区别
						// 关于这一块的逻辑,细心的一点的会发现,这里漏了实例化后置处理、初始化前置处理这两个方法。
						// 而是在提前返回对象后,直接执行了初始化后置处理器就完成了bean的整个流程,
						// 相当于是提供了一个短路的操作,不再经过Spring提供的繁杂的各种处理
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			// 设置是否已经提前实例化
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

跟进applyBeanPostProcessorsBeforeInstantiation()代码查看。这里只要有一个 InstantiationAwareBeanPostProcessor 返回的结果不为空,则直接返回,说明多个 InstantiationAwareBeanPostProcessor 只会生效靠前的一个,注意单词Instantiation和Initialization区别

	/**
	 * spring bean 初始化流程
	 * Bean 初始化(Initialization)
	 * 1.@PoseConstruct 方法
	 * 2.实现InitializingBean 接口的afterPropertiesSet()方法
	 * 3.自定义初始化方法
	 */
	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				// 如果为空,表示不作任何调整
				// 这里只要有一个 InstantiationAwareBeanPostProcessor 返回的结果不为空,则直接返回,
				// 说明多个 InstantiationAwareBeanPostProcessor 只会生效靠前的一个
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

跟进applyBeanPostProcessorsAfterInitialization()方法,逻辑跟上面的是类似的,注意单词Instantiation和Initialization区别

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			// 有一个为空则也直接返回了
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

创建Bean

经过上面的步骤,有惊无险,我们来到了doCreateBean(beanName, mbdToUse, args)方法,这是真正进行Bean创建的地方,所以这里才是真的进入正文,前面都是打酱油走走过程。

当经历过 resolveBeforelnstantiation() 方法后,程序有两个选择 ,如果创建了代理或者说重写了 InstantiationAwareBeanPostProcessorpostProcessBeforelnstantiation() 方法并在方法 postProcessBeforelnstantiation() 中改变了 bean, 则直接返回就可以了 , 否则需要进行常规 bean 的创建。 而这常规 bean 的创建就是在 doCreateBean() 中完成的。

直接跟进doCreateBean()代码查看,代码很长,你忍一下。

	/**
	 * Actually create the specified bean. Pre-creation processing has already happened
	 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
	 * <p>Differentiates between default bean instantiation, use of a
	 * factory method, and autowiring a constructor.
	 *
	 * 实际创建指定的bean。
	 * 此时已经进行了预创建处理,例如检查 {@code postProcessBeforeInstantiation} 回调。
	 * <p>区分默认 bean 实例化、使用工厂方法和自动装配构造函数。
	 *
	 * @param beanName the name of the bean
	 * @param mbd the merged bean definition for the bean
	 * @param args explicit arguments to use for constructor or factory method invocation
	 * @return a new instance of the bean
	 * @throws BeanCreationException if the bean could not be created
	 * @see #instantiateBean
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 */
	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
		// 这个方法真正创建了Bean,创建一个Bean会经过 创建对象 > 依赖注入 > 初始化
		// 这三个过程,在这个过程中,BeanPostProcessor会穿插执行,

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//根据指定bean使用对应的策略创建新的实例,如工厂方法,构造函数自动注入,简单初始化
			// 这里真正的创建了对象
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.

		// 按照官方的注释来说,这个地方是Spring提供的一个扩展点,
		// 对程序员而言,我们可以通过一个实现了MergedBeanDefinitionPostProcessor的后置处理器
		// 来修改bd中的属性,从而影响到后续的Bean的生命周期
		// 不过官方自己实现的后置处理器并没有去修改bd,
		// 而是调用了applyMergedBeanDefinitionPostProcessors方法
		// 这个方法名直译过来就是-应用合并后的bd,也就是说它这里只是对bd做了进一步的使用而没有真正的修改
		synchronized (mbd.postProcessingLock) {
			// bd只允许被处理一次
			if (!mbd.postProcessed) {
				try {
					// 应用合并后的bd
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				// 标注这个bd已经被MergedBeanDefinitionPostProcessor的后置处理器处理过
				// 那么在第二次创建Bean的时候,不会再次调用applyMergedBeanDefinitionPostProcessors
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		//是否需要提前暴露mbd.isSingleton() && this.allowCircularReferences &&
		//				isSingletonCurrentlyInCreation(beanName)
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
			//getEarlyBeanReference对bean再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor
			//其中我们熟悉的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不做任何处理
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		// 初始化实例
		Object exposedObject = bean;
		try {
			//对bean进行填充,对各个属性进行注入,可能存在依赖其他bean的属性,则会递归初始化依赖bean
			populateBean(beanName, mbd, instanceWrapper);
			//调用初始化方法
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			//earlySingletonReference只有在检测到循环依赖的情况下才不为空
			if (earlySingletonReference != null) {
				//如果exposedObject没有在初始化方法中被改变,也就是没有被增强
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					//检测依赖
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					/**
					 * 因为bean创建完成后,其依赖的bean也一定是创建完成的
					 * 如果actualDependentBeans不为空,则说明依赖的bean还没有被完全创建好
					 * 也就是说还存在循环依赖
					 */
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			//根据scope注册bean
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

分析一下这个函数设计思路:

  • 如果是单例则需要首先清除缓存。
  • 实例化 bean ,将 BeanDefinition 转换为 BeanWrapper。 转换是一个复杂的过程,但是我们可以尝试概括大致的功能,如下所示。
    • 如果存在工厂方法则使用工厂方法进行实例化。
    • 如果一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造 函数并进行实例化。
    • 如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行 bean 的实例化。
  • MergedBeanDefinitionPostProcessor的应用。 bean 合并后的处理, Autowired 注解正是通过此方法实现诸如类型的预解析。
  • 依赖处理。 在 Spring 中会有循环依赖的情况,例如,当 A 中含有 B 的属性,而 B 中又含有 A 的属性 时就会构成一个循环依赖,此时如果 A 和 B 都是单例,那么在 Spring 中的处理方式就是当创建 B 的时候,涉及自动注入 A 的步骤,并不是直接去再次创建 A,而是通过放入缓存中的 ObjectFactory 来创建实例,这样就解决了循环依赖的问题。
  • 属性填充。 将所有属性填充至 bean 的实例中。
  • 调用初始化方法。在属性填充完成后,这里会进行初始化方法的调用。
  • 循环依赖检查。 之前有提到过,在 Sping 中解决循环依赖只对单例有效,而对于 prototype 的 bean, Spring 没有好的解决办法,唯一要做的就是抛出异常。 在这个步骤里面会检测已经加载的 bean 是否 已经出现了依赖循环,并判断是再需要抛出异常。
  • 注册 DisposableBean。 如果配置了 destroy-method,这里需要注册以便于在销毁时候调用。
  • 完成创建井返回。

可以看到上面的步骤非常的繁琐,每一步骤都使用了大量的代码来完成其功能,最复杂也是最难以理解的当属循环依赖的处理,在真正进入 doCreateBean() 前我们有必要先了解下循环依赖,这里会在下一篇文章Spring Ioc源码分析系列--自动注入循环依赖的处理图文并茂去分析。

下面就按照上述的点逐个分析,接下来肯定是枯燥无味的,那开始吧。

清除factoryBeanInstanceCache缓存

首先如果是单例,会到factoryBeanInstanceCache中获取是否存在缓存,如果有这里就会从缓存里获取一个instanceWrapper,不需要再去走复杂的创建流程了。

对应代码如下:

		if (mbd.isSingleton()) {
			// 你可以暂时理解为,这个地方返回的就是个null
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
实例化 bean

又到了实例化bean,是不是反反复复看了很多次,到底哪里才真的创建一个bean,别慌,这里真的是真正创建bean的地方了,再套娃就是狗。

跟进createBeanInstance(beanName, mbd, args)方法。这个方法干了哪几件事?

  • 首先尝试调用obtainFromSupplier()实例化bean
  • 尝试调用instantiateUsingFactoryMethod()实例化bean
  • 根据给定参数推断构造函数实例化bean
  • 以上均无,则使用默认构造函数实例化bean
	/**
	 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
	 * factory method, constructor autowiring, or simple instantiation.
	 *
	 * 使用适当的实例化策略为指定的 bean 创建一个新实例:工厂方法、构造函数自动装配或简单实例化。
	 *
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @param args explicit arguments to use for constructor or factory method invocation
	 * @return a BeanWrapper for the new instance
	 * @see #obtainFromSupplier
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 * @see #instantiateBean
	 */
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		// 确保此时实际解析了 bean 类。
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}
		// 通过bd中提供的instanceSupplier来获取一个对象
		// 正常bd中都不会有这个instanceSupplier属性,这里也是Spring提供的一个扩展点,但实际上不常用
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		//如果工厂方法不为null,则使用工厂方法初始化策略
		// bd中提供了factoryMethodName属性,那么要使用工厂方法的方式来创建对象,
		// 工厂方法又会区分静态工厂方法跟实例工厂方法
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		// 在原型模式下,如果已经创建过一次这个Bean了,那么就不需要再次推断构造函数了
		// 是否推断过构造函数
		boolean resolved = false;
		// 构造函数是否需要进行注入
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				//一个类里面有多个构造函数,每个构造函数都有不同的参数,所以调用前需要根据参数锁定要调用的构造函数或工厂方法
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		//如果已经解析过则使用解析好的构造函数方法,不需要再次锁定
		if (resolved) {
			if (autowireNecessary) {
				//构造函数自动注入
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				//使用默认构造函数进行构造
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring?
		//需要根据参数解析构造函数
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			//构造函数自动注入
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		// 默认构造的首选构造函数?
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		//使用默认构造函数
		return instantiateBean(beanName, mbd);
	}

接下来分析以上几点,算了不分析,太长了。我在另一篇文章Spring Ioc源码分析系列--实例化Bean的几种方法会填坑。这里会详细分析上面的几点,好好把握,估计看到这都不知道啥跟啥了。

MergedBeanDefinitionPostProcessor的应用

到这里我们已经实例化了一个bean对象,但是这个bean只是个半成品,空有外壳而无内在,所以接下来的工作就是对里面的内容进行填充。那毫无疑问,按照Spring的尿性,肯定会在真正开始之前给你一个扩展点,让你还要机会在属性填充之前修改某些东西。我们经常使用的@Autowired注解就是在这里实现的,后续会写一篇Spring Ioc源码分析系列--@Autowired注解的实现原理结合源码和例子去分析它的实现。

跟进代码查看,比较简单,就是获取所有的MergedBeanDefinitionPostProcessor,然后依次执行它的postProcessMergedBeanDefinition()方法。

	/**
	 * Apply MergedBeanDefinitionPostProcessors to the specified bean definition,
	 * invoking their {@code postProcessMergedBeanDefinition} methods.
	 *
	 * 将 MergedBeanDefinitionPostProcessors 应用于指定的 bean 定义,
	 * 调用它们的 {@code postProcessMergedBeanDefinition} 方法。
	 *
	 * 可以看到这个方法的代码还是很简单的,
	 * 就是调用了MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法
	 *
	 * @param mbd the merged bean definition for the bean
	 * @param beanType the actual type of the managed bean instance
	 * @param beanName the name of the bean
	 * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
	 */
	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

这部分主要是为了处理循环依赖而做的准备,这里会根据earlySingletonExposure参数去判断是否允许循环依赖,如果允许,则会调用addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))方法将bean的早期引用放入到singletonFactories中。关于循环依赖的详细处理过程,可以在下一篇文章Spring Ioc源码分析系列--自动注入循环依赖的处理里看到。

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		//是否需要提前暴露mbd.isSingleton() && this.allowCircularReferences &&
		//				isSingletonCurrentlyInCreation(beanName)
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
			//getEarlyBeanReference对bean再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor
			//其中我们熟悉的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不做任何处理
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

跟进addSingletonFactory()方法,可以看到这里会先把早期引用放入到singletonFactories三级缓存中。

	/**
	 * Add the given singleton factory for building the specified singleton
	 * if necessary.
	 *
	 * 如有必要,添加给定的单例工厂以构建指定的单例。
	 *
	 * <p>To be called for eager registration of singletons, e.g. to be able to
	 * resolve circular references.
	 *
	 * 被提前注册的单例Bean调用,例如用来解决循环依赖
	 *
	 * @param beanName the name of the bean
	 * @param singletonFactory the factory for the singleton object
	 */
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			if (!this.singletonObjects.containsKey(beanName)) {
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
	}

那放入到singletonFactories里面的是什么呢?从上面可以看到,这是一个lambada表达式,调用的方法的是getEarlyBeanReference(),跟进代码查看。

	/**
	 * Obtain a reference for early access to the specified bean,
	 * typically for the purpose of resolving a circular reference.
	 *
	 * 获取对指定 bean 的早期访问的引用,通常用于解析循环引用。
	 *
	 * @param beanName the name of the bean (for error handling purposes)
	 * @param mbd the merged bean definition for the bean
	 * @param bean the raw bean instance
	 * @return the object to expose as bean reference
	 */
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					// 对 bean 再一次依赖引用
					// 主要应用 SmartInstantiationAwareBeanPostProcessor, 
					// 其中我们熟知的 AOP 就是在这里将 advice 动态织入 bean 中, 若没有则直接返回 bean ,不做任何处理
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

到这里会已经完成了bean的实例化,早期引用的暴露,那接下来就到了属性填充的部分,开始对bean进行各种赋值,让一个空壳半成品bean完善成一个有血有肉的正常bean。

这里可能存在依赖其他bean的属性,则会递归初始化依赖bean。

populateBean() 函数中提供了这样的处理流程。

  • InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterinstantiation 函数的应用, 此函数可以控制程序是否继续进行属性填充。
  • 根据注入类型( byName/byType ),提取依赖的 bean,并统一存入 PropertyValues 中。
  • 应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法, 对属性获取完毕填充前对属性的再次处理,典型应用是 RequiredAnnotationBeanPostProcessor 类中对属性的验证。
  • 将所有 PropertyValues 中的属性填充至 BeanWrapper 中。

跟进代码查看,又很长,这一块的代码真的是又臭又长。但是注释很详细,可以跟着看看。

	/**
	 * Populate the bean instance in the given BeanWrapper with the property values
	 * from the bean definition.
	 *
	 * 使用 bean 定义中的属性值填充给定 BeanWrapper 中的 bean 实例。
	 *
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @param bw the BeanWrapper with bean instance
	 */
	@SuppressWarnings("deprecation")  // for postProcessPropertyValues
	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				//没有可填充的属性
				return;
			}
		}

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		boolean continueWithPropertyPopulation = true;

		//给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前来改变 bean
		//如:可以用来支持属性注入的类型
		// 满足两个条件,不是合成类 && 存在InstantiationAwareBeanPostProcessor
		// 其中InstantiationAwareBeanPostProcessor主要作用就是作为Bean的实例化前后的钩子
		// 外加完成属性注入,对于三个方法就是
		// postProcessBeforeInstantiation  创建对象前调用
		// postProcessAfterInstantiation   对象创建完成,@AutoWired注解解析后调用
		// postProcessPropertyValues(已过期,被postProcessProperties替代) 进行属性注入
		// 下面这段代码的主要作用就是我们可以提供一个InstantiationAwareBeanPostProcessor
		// 提供的这个后置处理如果实现了postProcessAfterInstantiation方法并且返回false
		// 那么可以跳过Spring默认的属性注入,但是这也意味着我们要自己去实现属性注入的逻辑
		// 所以一般情况下,我们也不会这么去扩展
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					//返回值为是否继续填充bean
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		//如果后处理器发出停止填充命令则终止后续操作
		if (!continueWithPropertyPopulation) {
			return;
		}

		// 这里其实就是判断XML是否提供了属性相关配置
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		// 确认注入模型
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();

		// 主要处理byName跟byType两种注入模型,byConstructor这种注入模型在创建对象的时候已经处理过了
		// 这里都是对自动注入进行处理,byName跟byType两种注入模型均是依赖setter方法
		// byName,根据setter方法的名字来查找对应的依赖,例如setA,那么就是去容器中查找名字为a的Bean
		// byType,根据setter方法的参数类型来查找对应的依赖,例如setXx(A a),就是去容器中查询类型为A的bean
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				//根据名称注入
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				//根据类型注入
				autowireByType(beanName, mbd, bw, newPvs);
			}
			// pvs是XML定义的属性
			// 自动注入后,bean实际用到的属性就应该要替换成自动注入后的属性
			pvs = newPvs;
		}

		//后置处理器已经初始化
		// 检查是否有InstantiationAwareBeanPostProcessor
		// 前面说过了,这个后置处理器就是来完成属性注入的
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//需要依赖检查
		//  是否需要依赖检查,默认是不会进行依赖检查的
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		// 下面这段代码有点麻烦了,因为涉及到版本问题
		// 其核心代码就是调用了postProcessProperties完成了属性注入
		PropertyDescriptor[] filteredPds = null;
		// 存在InstantiationAwareBeanPostProcessor,我们需要调用这类后置处理器的方法进行注入
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					// 这句就是核心
					// Autowired 是通过 AutowiredAnnotationBeanPostProcessor#postProcessProperties() 实现的
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							// 得到需要进行依赖检查的属性的集合
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						//对所有需要依赖检查的属性做后置处理
						//  这个方法已经过时了,放到这里就是为了兼容老版本
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		// 需要进行依赖检查
		if (needsDepCheck) {
			if (filteredPds == null) {
				// 得到需要进行依赖检查的属性的集合
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			//依赖检查,对应depends-on属性,3.0已经弃用此属性
			// 对需要进行依赖检查的属性进行依赖检查
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		// 将XML中的配置属性应用到Bean上
		if (pvs != null) {
			//将属性应用到bean中
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

这里看到这里会根据byName或者byType方式寻找依赖,然后调用applyPropertyValues()将属性注入到BeanWrapperImpl里。

先来看autowireByName()方法,顾名思义,这里会根据属性名去获取依赖。

	/**
	 * Fill in any missing property values with references to
	 * other beans in this factory if autowire is set to "byName".
	 * 
	 * 如果 autowire 设置为“byName”,则使用对该工厂中其他 bean 的引用填充任何缺少的属性值。
	 * 
	 * @param beanName the name of the bean we're wiring up.
	 * Useful for debugging messages; not used functionally.
	 * @param mbd bean definition to update through autowiring
	 * @param bw the BeanWrapper from which we can obtain information about the bean
	 * @param pvs the PropertyValues to register wired objects with
	 */
	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		//寻找bw中需要依赖注入的属性值
		// 得到符合下面条件的属性名称
		// 1.有setter方法
		// 2.需要进行依赖检查
		// 3.不包含在XML配置中
		// 4.不是简单类型(基本数据类型,枚举,日期等)
		// 这里可以看到XML配置优先级高于自动注入的优先级
		// 不进行依赖检查的属性,也不会进行属性注入
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			if (containsBean(propertyName)) {
				//递归初始化相关bean
				Object bean = getBean(propertyName);
				// 将自动注入的属性添加到pvs中去
				pvs.add(propertyName, bean);
				//注册依赖
				registerDependentBean(propertyName, beanName);
				if (logger.isTraceEnabled()) {
					logger.trace("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}

接下来看autowireByType(),该方法会根据属性的类型去获取依赖。也比较简单明了。

	/**
	 * Abstract method defining "autowire by type" (bean properties by type) behavior.
	 * <p>This is like PicoContainer default, in which there must be exactly one bean
	 * of the property type in the bean factory. This makes bean factories simple to
	 * configure for small namespaces, but doesn't work as well as standard Spring
	 * behavior for bigger applications.
	 * 
	 * 定义“按类型自动装配”(按类型的 bean 属性)行为的抽象方法。 
	 * <p>这类似于 PicoContainer 默认值,其中 bean 工厂中必须只有一个属性类型的 bean。
	 * 这使得 bean 工厂易于为小型命名空间配置,但不能像标准 Spring 行为那样为大型应用程序工作。
	 * 
	 * @param beanName the name of the bean to autowire by type
	 * @param mbd the merged bean definition to update through autowiring
	 * @param bw the BeanWrapper from which we can obtain information about the bean
	 * @param pvs the PropertyValues to register wired objects with
	 */
	protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		// 这个类型转换器,主要是在处理@Value时需要使用
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}

		Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
		//寻找bw中需要依赖注入的属性
		// 得到符合下面条件的属性名称
		// 1.有setter方法
		// 2.需要进行依赖检查
		// 3.不包含在XML配置中
		// 4.不是简单类型(基本数据类型,枚举,日期等)
		// 这里可以看到XML配置优先级高于自动注入的优先级
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			try {
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				// Don't try autowiring by type for type Object: never makes sense,
				// even if it technically is a unsatisfied, non-simple property.
				// 不要尝试为 Object 类型按类型自动装配:永远没有意义,即使它在技术上是一个不令人满意的、不简单的属性。
				if (Object.class != pd.getPropertyType()) {
					//探测指定属性的set方法
					// 这里获取到的就是setter方法的参数,因为我们需要按照类型进行注入嘛
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// Do not allow eager init for type matching in case of a prioritized post-processor.
					// 如果是PriorityOrdered在进行类型匹配时不会去匹配factoryBean
					// 如果不是PriorityOrdered,那么在查找对应类型的依赖的时候会会去匹factoryBean
					// 这就是Spring的一种设计理念,实现了PriorityOrdered接口的Bean被认为是一种
					// 最高优先级的 Bean,这一类的Bean在进行为了完成装配而去检查类型时,
					// 不去检查 factoryBean
					// 具体可以参考PriorityOrdered接口上的注释文档
					boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
					// 将参数封装成为一个依赖描述符
					// 依赖描述符会通过:依赖所在的类,字段名/方法名,依赖的具体类型等来描述这个依赖
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					/**
					 * 解析指定beanName的属性所匹配的值,并把解析到的属性名存储在autowiredBeanNames中,
					 * 当属性存在多个封装bean时,如:
					 * @Autowire
					 * private List<A> list;
					 * 将会找到所有匹配A类型的bean并将其注入
					 * 解析依赖,这里会处理@Value注解
					 * 另外,通过指定的类型到容器中查找对应的bean
					 */
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
						// 将查找出来的依赖属性添加到pvs中,后面会将这个pvs应用到bean上
						pvs.add(propertyName, autowiredArgument);
					}
					// 注册bean直接的依赖关系
					for (String autowiredBeanName : autowiredBeanNames) {
						//注册依赖
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isTraceEnabled()) {
							logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
									propertyName + "' to bean named '" + autowiredBeanName + "'");
						}
					}
					autowiredBeanNames.clear();
				}
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}

属性依赖都获取完了,接下来就是按部就班的进行注入了。

跟进applyPropertyValues()方法,逻辑比较复杂。但是最终是调用了反射,给对应的属性进行了赋值,这里深入的就不再展开了。

	/**
	 * Apply the given property values, resolving any runtime references
	 * to other beans in this bean factory. Must use deep copy, so we
	 * don't permanently modify this property.
	 *
	 * 应用给定的属性值,解析对此 bean 工厂中其他 bean 的任何运行时引用。必须使用深拷贝,所以我们不会永久修改这个属性。
	 *
	 * @param beanName the bean name passed for better exception information
	 * @param mbd the merged bean definition
	 * @param bw the BeanWrapper wrapping the target object
	 * @param pvs the new property values
	 */
	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		if (pvs.isEmpty()) {
			return;
		}

		if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;

		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				// 快捷方式:按原样使用转换前的值。
				try {
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			original = mpvs.getPropertyValueList();
		}
		else {
			original = Arrays.asList(pvs.getPropertyValues());
		}

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		// 创建一个深拷贝副本,解析任何值的引用。
		List<PropertyValue> deepCopy = new ArrayList<>(original.size());
		boolean resolveNecessary = false;
		for (PropertyValue pv : original) {
			if (pv.isConverted()) {
				deepCopy.add(pv);
			}
			else {
				String propertyName = pv.getName();
				Object originalValue = pv.getValue();
				if (originalValue == AutowiredPropertyMarker.INSTANCE) {
					Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
					if (writeMethod == null) {
						throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
					}
					originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
				}
				// 给定一个 PropertyValue,返回一个值,必要时解析对工厂中其他 bean 的任何引用
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				Object convertedValue = resolvedValue;
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}
				// Possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				// 可能将转换后的值存储在合并的 bean 定义中,以避免对每个创建的 bean 实例进行重新转换。
				if (resolvedValue == originalValue) {
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				}
				else if (convertible && originalValue instanceof TypedStringValue &&
						!((TypedStringValue) originalValue).isDynamic() &&
						!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
					pv.setConvertedValue(convertedValue);
					deepCopy.add(pv);
				}
				else {
					resolveNecessary = true;
					deepCopy.add(new PropertyValue(pv, convertedValue));
				}
			}
		}
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

		// Set our (possibly massaged) deep copy.
		// 设置我们的(可能是经过按摩的)深拷贝。
		try {
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}
调用初始化方法

初始化方法的调用逻辑在initializeBean(beanName, exposedObject, mbd)里面,跟进代码查看。

一看是不是很清晰,所以以后再遇到问你啥啥啥方法先执行,直接叼面试官。

	/**
	 *
	 * initializeBean()方法依次调用四个方法
	 * 1.invokeAwareMethods()
	 * 2.applyBeanPostProcessorsBeforeInitialization()
	 * 3.invokeInitMethods()
	 * 4.applyBeanPostProcessorsAfterInitialization()
	 *
	 */
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			// 1.先调用实现 aware 接口的方法
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// 2.调用 BeanPostProcessor#postProcessBeforeInitialization()方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 3.调用初始化方法,例如实现了 InitializingBean#afterPropertiesSet() 方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			// 4.最后调用 BeanPostProcessor#postProcessAfterInitialization()
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
循环依赖检查

这一步主要是实现一个兜底的检测,避免出现注入了一个本该被代理的但是却注入了一个原生bean的情况,这部分会在循环依赖的文章里结合来分析。

先看下代码。

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			//earlySingletonReference只有在检测到循环依赖的情况下才不为空
			if (earlySingletonReference != null) {
				//如果exposedObject没有在初始化方法中被改变,也就是没有被增强
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					//检测依赖
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					/**
					 * 因为bean创建完成后,其依赖的bean也一定是创建完成的
					 * 如果actualDependentBeans不为空,则说明依赖的bean还没有被完全创建好
					 * 也就是说还存在循环依赖
					 */
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}
注册 DisposableBean

这也是一个回调的操作,注册一些销毁的方法。Spring 中不但提供了对于初始化方法的扩展人口 , 同样也提供了销毁方法的扩展入口,对 于销毁方法的扩展,除了我们熟知的配置属性 destroy-method 方法外,用户还可以注册后处理器 DestructionAwareBeanPostProcessor 来统一处理 bean 的销毁方法,跟进代码registerDisposableBeanIfNecessary()

	/**
	 * Add the given bean to the list of disposable beans in this factory,
	 * registering its DisposableBean interface and/or the given destroy method
	 * to be called on factory shutdown (if applicable). Only applies to singletons.
	 *
	 * 将给定的 bean 添加到该工厂的一次性 bean 列表中,
	 * 注册其 DisposableBean 接口和或在工厂关闭时调用的给定销毁方法(如果适用)。仅适用于单例。
	 *
	 * @param beanName the name of the bean
	 * @param bean the bean instance
	 * @param mbd the bean definition for the bean
	 * @see RootBeanDefinition#isSingleton
	 * @see RootBeanDefinition#getDependsOn
	 * @see #registerDisposableBean
	 * @see #registerDependentBean
	 */
	protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
			if (mbd.isSingleton()) {
				// Register a DisposableBean implementation that performs all destruction
				// work for the given bean: DestructionAwareBeanPostProcessors,
				// DisposableBean interface, custom destroy method.
				// 注册一个为给定 bean 执行所有销毁工作的 DisposableBean 实现:DestructionAwareBeanPostProcessors、DisposableBean 接口、自定义销毁方法。
				/**
				 * 单例模式下需要销毁的bean,此方法中会处理实现DisposableBean的bean
				 * 并且对所有的bean使用DestructionAwareBeanPostProcessors处理
				 * DisposableBean DestructionAwareBeanPostProcessors
				 */
				registerDisposableBean(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
			else {
				// A bean with a custom scope...
				// 自定义scope处理
				Scope scope = this.scopes.get(mbd.getScope());
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
				}
				scope.registerDestructionCallback(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
		}
	}

本文主要分析了doCreateBean()方法,但是讲得比较粗糙。回忆一下本文的思路,首先是通过类名反射得到一个class对象,然后推断构造函数去实例化得到一个bean对象,当然这部分没有深入细节去说,分多了一篇文章。然后通过byNamebyType两种方式去获取依赖注入,之后通过反射将属性注入到对象中。除去一些边边角角的校验,总的思路就是这样,还是相对清晰的,就是细节比较多。

这里牵扯的东西比较多,也算是Ioc里面比较难啃的部分了。我回看一遍我写的文章,觉得整体言不达意,脑子里想十分,说出来可能只有六分,写出来的就剩三分了。

个人水平有限,如有错误,还请指出。

如果有人看到这里,那在这里老话重提。与君共勉,路漫漫其修远兮,吾将上下而求索。

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK