Spring 源码解析(五)深入探索 bean 的实例化 -- doCreateBean 方法的解析

991 阅读10分钟

前面我们分析了 Spring IOC 容器的依赖注入与 bean 的实例化 ,今天我们就其中的 doCreateBean 方法来看看它具体的实现原理

继续之前的 bean 的实例化过程与其中的依赖注入的实现的分析

  • AbstractBeanFactory
    • doGetBean 获取 bean 实例
  • DefaultSingletonRegistry
    • getSingleton 获取单例实例
    • 三级缓存 解决循环依赖
  • AbstractAutowireCapableBeanFactory
    • createBean 创建 bean 实例的准备
    • doCreateBean 创建 bean 实例
    • applyMergedBeanDefinitionPostProcessors 处理 @Autowriet 和 @Value
    • populateBean 给 bean 实例注入属性值(依赖注入)

分析

我们现在分析创建 bean 实例的相关源码,在之前的文章我们知道 doCreateBean 大致做了5件事:

  1. 创建 bean 实例: createBeanInstance
  2. 调用 BeanDefinition 属性合并完成后的 BeanPostProcessor 后置处理器
  3. 填充 bean 实例的属性:populateBean
  4. 调用 bean 的初始化方法:initializeBean
  5. 注册 bean 的销毁逻辑: registerDisposableBeanIfNecessary

最后返回创建好的 bean 实例对象

创建 bean 实例:createBeanInstance

使用适当的实例化策略为指定的 bean 创建一个新实例:工厂方法、构造函数自动装配或简单实例化。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// 尝试去获取 bean 里面的 class 对象
        Class<?> beanClass = resolveBeanClass(mbd, beanName);
	// 检查是否有权通过反射创建 private 的 Class
	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());
	}
	// 使用工厂方法创建实例
	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}
	// 如果工厂方法不为空,则使用工厂方法初始化策略
	if (mbd.getFactoryMethodName() != null) {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}

	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);
		}
	}

	// 使用带参的构造函数进行装配
	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);
	}

	// 使用默认的构造函数
	return instantiateBean(beanName, mbd);
}

我们注意到如果工厂方法不为空,则使用工厂方法初始化策略,在这主要是调用 ConstructorResolver#instantiateUsingFactoryMethod 方法来创建 bean 实例。

public BeanWrapper instantiateUsingFactoryMethod(
		String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

	BeanWrapperImpl bw = new BeanWrapperImpl();
	// 初始化 BeanWrapperImpl
	// 向 BeanWrapper 对象中添加 ConversionService 对象和属性编辑器 PropertyEditor 对象
	this.beanFactory.initBeanWrapper(bw);

	Object factoryBean;
	Class<?> factoryClass;
	boolean isStatic;

	// 工厂名不为空
	String factoryBeanName = mbd.getFactoryBeanName();
	if (factoryBeanName != null) {
		if (factoryBeanName.equals(beanName)) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
					"factory-bean reference points back to the same bean definition");
		}
		// 获取工厂实例
		factoryBean = this.beanFactory.getBean(factoryBeanName);
		if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
			throw new ImplicitlyAppearedSingletonException();
		}
		factoryClass = factoryBean.getClass();
		isStatic = false;
	}
	else {
		// 工厂名为null,则其可能是一个静态工厂
		// 静态工厂创建bean,必须要提供工厂的全类名
		if (!mbd.hasBeanClass()) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
					"bean definition declares neither a bean class nor a factory-bean reference");
		}
		factoryBean = null;
		factoryClass = mbd.getBeanClass();
		isStatic = true;
	}
	// 工厂方法
	Method factoryMethodToUse = null;
	ArgumentsHolder argsHolderToUse = null;
	Object[] argsToUse = null;
	// 工厂方法的参数
	// 如果指定了构造参数则直接使用
	// 在调用 getBean 方法的时候指定了方法参数
	if (explicitArgs != null) {
		argsToUse = explicitArgs;
	}
	else {
		// 没有指定,则尝试从配置文件中解析
		Object[] argsToResolve = null;

		// 首先尝试从缓存中获取
		synchronized (mbd.constructorArgumentLock) {
			factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;

			// 获取缓存中的构造函数或者工厂方法
			if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
				// 获取缓存中的构造参数
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					// 获取缓存中的构造函数参数的包可见字段
					argsToResolve = mbd.preparedConstructorArguments;
				}
			}
		}
		// 缓存中存在,则解析存储在 BeanDefinition 中的参数
		// 如给定方法的构造函数 A(int ,int ),则通过此方法后就会把配置文件中的("1","1")转换为 (1,1)
		// 缓存中的值可能是原始值也有可能是最终值
		if (argsToResolve != null) {
			argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
		}
	}
	//  调用getBean方法没有传参,同时也是第一次使用工厂方法
	if (factoryMethodToUse == null || argsToUse == null) {
		// 获取工厂方法的类全名称
		factoryClass = ClassUtils.getUserClass(factoryClass);

		List<Method> candidateList = null;
		if (mbd.isFactoryMethodUnique) {
			if (factoryMethodToUse == null) {
				factoryMethodToUse = mbd.getResolvedFactoryMethod();
			}
			// 获取所有符合条件的方法
			if (factoryMethodToUse != null) {
				candidateList = Collections.singletonList(factoryMethodToUse);
			}
		}
		if (candidateList == null) {
			candidateList = new ArrayList<>();
			// 检索所有方法,这里是对方法进行过滤
			Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
			for (Method candidate : rawCandidates) {
				// 如果有static 且为工厂方法,则添加到 candidateSet 中
				if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
					candidateList.add(candidate);
				}
			}
		}
		// 当与工厂方法同名的候选方法只有一个,且调用getBean方法时没有传参,
		// 且没有缓存过参数,直接通过调用实例化方法执行该候选方法
		if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
			Method uniqueCandidate = candidateList.get(0);
			if (uniqueCandidate.getParameterCount() == 0) {
				mbd.factoryMethodToIntrospect = uniqueCandidate;
				synchronized (mbd.constructorArgumentLock) {
					mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
					mbd.constructorArgumentsResolved = true;
					mbd.resolvedConstructorArguments = EMPTY_ARGS;
				}
				bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
				return bw;
			}
		}

		Method[] candidates = candidateList.toArray(new Method[0]);
		// 排序构造函数
		// public 构造函数优先参数数量降序,非public 构造函数参数数量降序
		AutowireUtils.sortFactoryMethods(candidates);
		// 有多个与工厂方法同名的候选方法时,进行排序。public的方法会往前排,然后参数个数多的方法往前排
		ConstructorArgumentValues resolvedValues = null;
		boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
		int minTypeDiffWeight = Integer.MAX_VALUE;
		Set<Method> ambiguousFactoryMethods = null;

		int minNrOfArgs;
		// 如果调用getBean方法时有传参,那么工厂方法最少参数个数要等于传参个数
		if (explicitArgs != null) {
			minNrOfArgs = explicitArgs.length;
		}
		else {
			// getBean() 没有传递参数,则需要解析保存在 BeanDefinition 构造函数中指定的参数
			if (mbd.hasConstructorArgumentValues()) {
				// 构造函数的参数
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				resolvedValues = new ConstructorArgumentValues();
				// 解析构造函数的参数
				// 将该 bean 的构造函数参数解析为 resolvedValues 对象,其中会涉及到其他 bean
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}
			else {
				minNrOfArgs = 0;
			}
		}

		LinkedList<UnsatisfiedDependencyException> causes = null;
		// 遍历同名候选方法
		for (Method candidate : candidates) {
			// 获取候选方法的参数列表
			Class<?>[] paramTypes = candidate.getParameterTypes();

			if (paramTypes.length >= minNrOfArgs) {
				ArgumentsHolder argsHolder;
				// 在调用getBean方法时传的参数不为空,则工厂方法的参数个数需要与
				// 传入的参数个数严格一致
				if (explicitArgs != null) {
					// 显示给定参数,参数长度必须完全匹配
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					argsHolder = new ArgumentsHolder(explicitArgs);
				}
				else {
					try {
						String[] paramNames = null;
						// 获取 ParameterNameDiscoverer 对象
						// ParameterNameDiscoverer 是用于解析方法和构造函数的参数名称的接口,为参数名称探测器
						ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
						if (pnd != null) {
							paramNames = pnd.getParameterNames(candidate);
						}
						//当传入的参数为空,需要根据工厂方法的参数类型注入相应的bean
						argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
								paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
					}
					catch (UnsatisfiedDependencyException ex) {
						···
						continue;
					}
				}
				// isLenientConstructorResolution 判断解析构造函数的时候是否以宽松模式还是严格模式
				// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
				// 宽松模式:使用具有"最接近的模式"进行匹配
				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				// 代表最接近的类型匹配,则选择作为构造函数
				if (typeDiffWeight < minTypeDiffWeight) {
					factoryMethodToUse = candidate;
					argsHolderToUse = argsHolder;
					argsToUse = argsHolder.arguments;
					minTypeDiffWeight = typeDiffWeight;
					ambiguousFactoryMethods = null;
				}
				// 如果具有相同参数数量的方法具有相同的类型差异权重,则收集此类型选项
				// 但是,仅在非宽松构造函数解析模式下执行该检查,并显式忽略重写方法(具有相同的参数签名)
				else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
						!mbd.isLenientConstructorResolution() &&
						paramTypes.length == factoryMethodToUse.getParameterCount() &&
						!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
					// 查找到多个可匹配的方法
					if (ambiguousFactoryMethods == null) {
						ambiguousFactoryMethods = new LinkedHashSet<>();
						ambiguousFactoryMethods.add(factoryMethodToUse);
					}
					ambiguousFactoryMethods.add(candidate);
				}
			}
		}
		// 没有可执行的工厂方法,抛出异常
		···

		if (explicitArgs == null && argsHolderToUse != null) {
			mbd.factoryMethodToIntrospect = factoryMethodToUse;
			// 将解析的构造函数加入缓存
			argsHolderToUse.storeCache(mbd, factoryMethodToUse);
		}
	}

	bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
	return bw;
}

可以看到它方法很长,但不难理解都是在为实例化 bean 做准备,最终都是去调用 instantiate 方法来通过执行工厂方法来创建 bean 示例。

private Object instantiate(String beanName, RootBeanDefinition mbd,
		@Nullable Object factoryBean, Method factoryMethod, Object[] args) {

	try {
		if (System.getSecurityManager() != null) {
			return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
					this.beanFactory.getInstantiationStrategy().instantiate(
							mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args),
					this.beanFactory.getAccessControlContext());
		}
		else {
			// 通过执行工厂方法来创建 bean 示例
			return this.beanFactory.getInstantiationStrategy().instantiate(
					mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean instantiation via factory method failed", ex);
	}
}

好,我们回过头去看 AbstractAutowireCapableBeanFactory#createBeanInstance 方法 ,发现后续也是会去调用 instantiate 方法来通过执行工厂方法来创建 bean 示例。跟进去最终发现都是通过反射来获取实例。

调用 BeanDefinition 属性合并完成后的 BeanPostProcessor 后置处理器

看完 createBeanInstance 方法后,我们继续回到 doCreateBean 方法内继续看

synchronized (mbd.postProcessingLock) {
	if (!mbd.postProcessed) {
		try {
			//被 @Autowired、@Value 标记的属性在这里获取
			applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
		}
		// 异常处理 ···
		mbd.postProcessed = true;
	}
}

可以看到主要是执行 applyMergedBeanDefinitionPostProcessors 方法,该方法主要执行了MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 在该方法里面打断点,发现该接口是子类 AutowiredAnnotationBeanPostProcessor 去实现的,那 AutowiredAnnotationBeanPostProcessor 创建时如下:

public AutowiredAnnotationBeanPostProcessor() {
	this.autowiredAnnotationTypes.add(Autowired.class);
	this.autowiredAnnotationTypes.add(Value.class);
	try {
		this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
				ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
		logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
	} catch (ClassNotFoundException ex) {
		// JSR-330 API not available - simply skip.
	}
}

会添加 Autowired、Value 、Inject 标签,所以这一步主要是在这获取 @Autowired、@Value 标记的属性

填充 bean 实例的属性:populateBean

我们继续看 doCreateBean 方法的后续,为创建好的 bean 实例填充属性

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	···
	// 给 InstantiationAwareBeanPostProcessors 最后一次机会在属性注入前修改 Bean 的属性值,也可以控制是否继续填充 Bean
	// 具体通过调用 postProcessAfterInstantiation 方法,如果调用返回 false,表示不必继续进行依赖注入,直接返回
	// 主要是让用户可以自定义属性注入。比如用户实现一个 InstantiationAwareBeanPostProcessor 类型的后置处理器,
	// 并通过 postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。
	boolean continueWithPropertyPopulation = true;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					continueWithPropertyPopulation = false;
					break;
				}
			}
		}
	}
	//如果上面设置 continueWithPropertyPopulation = false,表明用户可能已经自己填充了
	// bean 的属性,不需要 Spring 帮忙填充了。此时直接返回即可
	if (!continueWithPropertyPopulation) {
		return;
	}
	// pvs 是一个 MutablePropertyValues 实例,里面实现了 PropertyValues 接口,
	// 提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
	// 获取 BeanDefinition 里面为 Bean 设置上的属性值
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
	// 根据 Bean 配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在 xml 文件中有显式的配置
	// 如果设置了相关的依赖装配方式,会遍历 Bean 中的属性,根据类型或名称来完成相应注入,无需额外配置
	int resolvedAutowireMode = mbd.getResolvedAutowireMode();
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		// 根据 beanName 进行 autowiring 自动装配处理
		// ps: <bean id="A" class="com.mrlsm.spring.A"  autowire="byName"></bean>
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		// 根据 Bean 的类型进行 autowiring 自动装配处理
		// ps: <bean id="A" class="com.mrlsm.spring.A"  autowire="byType"></bean>
		if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}
	// 容器是否注册了 InstantiationAwareBeanPostProcessor
	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	// 是否进行依赖检查,默认为 false
	boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

	PropertyDescriptor[] filteredPds = null;
	if (hasInstAwareBpps) {
		if (pvs == null) {
			pvs = mbd.getPropertyValues();
		}
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// 在这里会对 @Autowired 标记的属性进行依赖注入
				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;
			}
		}
	}
	// 依赖检查,对应 depend-on 属性,3.0已经弃用此属性
	if (needsDepCheck) {
		// 过滤出所有需要进行依赖检查的属性编辑器
		if (filteredPds == null) {
			filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		}
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}

	if (pvs != null) {
		// 最终将属性注入到 Bean 的 Wrapper 实例里,这里的注入主要是供显式配置了 autowiredbyName 或者 ByType 的属性注入,
		// 针对注解来讲,由于在 AutowiredAnnotationBeanPostProcessor 已经完成了注入,
		// 所以此处不执行
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

可以看到该方法主要是获取 BeanDefinition 里面为 Bean 设置上相关属性值,根据 name 或者 type 来为进行自动装配处理以及对 @Autowired 标记的属性进行依赖注入。 接下来就会调用 bean 的初始化方法。

调用 bean 的初始化方法:initializeBean

我们直接进入方法查看:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
        // bean 初始化的前置操作
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
		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()) {
        // bean 初始化的后置操作
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

发现初始化 bean 的时候主要进行了以下的步骤:

  1. 判断是否实现了 BeanNameAware,BeanClassLoaderAware, BeanFactoryAware 方法,如果有,则设置相关的属性。
  2. 调用 bean 初始化的前置(BeanPostProcessor)操作。
  3. 执行初始化的方法。 如果有initializingBean,则调用 afterPropertiesSet,如果有 InitMethod,则调用初始方法。
  4. 调用 bean 初始化的后置(BeanPostProcessor)操作。

注册 bean 的销毁逻辑: registerDisposableBeanIfNecessary

最后我们看下 doCreateBean 内最后一个方法来注册 bean 的销毁逻辑:

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
	AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
	// 不是 prototype 且需要销毁 bean
	if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
		if (mbd.isSingleton()) {
			// 单例模式下需要销毁的 bean
			registerDisposableBean(beanName,
					new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
		}
		else {
			// 自定义 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));
		}
	}
}

我们先看下 requiresDestruction 的判断:

protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
    return (bean.getClass() != NullBean.class &&
            (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
                                                                   DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}

逐一看一下 DisposableBeanAdapter 中的这两个方法:

public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
    // 如果实现了 DisposableBean 接口或者 AutoCloseable 接口,认为有销毁方法
    if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
        return true;
    }
    // 获取 beanDefinition 中的 destoryMethodName 属性
    String destroyMethodName = beanDefinition.getDestroyMethodName();
    if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName)) {
        // 如果是一个特殊值-(inferred),就看这个类有没有 close 或者 shutdown 方法
        return (ClassUtils.hasMethod(bean.getClass(), CLOSE_METHOD_NAME) ||
                ClassUtils.hasMethod(bean.getClass(), SHUTDOWN_METHOD_NAME));
    }
    // 看下有没有配置
    return StringUtils.hasLength(destroyMethodName);
}

// 如果容器中有注册 DestructionAwareBeanPostProcessor,则还会有以下这个方法的判断
public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcessor> postProcessors) {
    if (!CollectionUtils.isEmpty(postProcessors)) {
        for (BeanPostProcessor processor : postProcessors) {
            if (processor instanceof DestructionAwareBeanPostProcessor) {
                DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
                // 销毁方法是不是空
                if (dabpp.requiresDestruction(bean)) {
                    return true;
                }
            }
        }
    }
    return false;
}

确定是一个需要销毁的单例 bean 之后,spring 会把它包装成一个 DisposableBean 并且注册到 DefaultSingletonBeanRegistry:

public void registerDisposableBean(String beanName, DisposableBean bean) {
    synchronized (this.disposableBeans) {
        // 放入 disposableBeans map 中
        this.disposableBeans.put(beanName, bean);
    }
}

小结

好,这一篇我们主要了解了 doCreateBean 方法,简单来说,该方法主要是创建一个可以直接使用的 bean 并返回给调用层使用。到这我们就明白了 bean 实例的创建流程。

本文基于 spring-framework 5.2.10.RELEASE 版本进行分析