spring通过不同的方式创建bean

1:写在前面

本文在createBean方法分析的基础上进行分析,作为补充,详细分析spring通过构造函数,工厂方法等创建bean的过程。

2:createBeanInstance

源码:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
	...snip...
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	...snip...
}

继续:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// 获取待实例化bean的类型,后续实例化bean的时候使用
	Class<?> beanClass = resolveBeanClass(mbd, beanName);
	// <2021-03-20 02:56>
	// 以下条件同时满足则异常,因为此时无法创建实例对象
	// 1: 没有解析到bean的class类型
	// 2:类访问修饰符不是public的
	// 3:不允许访问非public的构造函数和方法
	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());
	}
	// <2021-03-20 04:36>
	// 获取Supplier
	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	// 如果是有Supplier则使用Supplier创建对象,并return
	if (instanceSupplier != null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}
	// <2021-03-20 05:21>
	// 通过factory-method创建bean
	if (mbd.getFactoryMethodName() != null) {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}
	/*** 到这里的话,就是通过构造函数来创建对象了 ***/
	
	// 是否已经解析处使用哪个构造函数的标记
	boolean resolved = false;
	// false:使用默认构造函数 true:使用带有参数的构造函数
	boolean autowireNecessary = false;
	// 如果是getbean时传入的参数为null
	// 这里是处理缓存有对应的构造函数的情况
	// 缓存的原因是查找对应构造函数比较耗性能
	// 对于scope为prototype的bean作用比较大
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			// 如果是需要的解析的构造函数不为空
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				// 标记为已经解析完毕
				resolved = true;
				// 设置构造函数参数是否已经解析
				// 1:解析了,则autowireNecessary 为true,则使用带有参数的构造函数
				// 2:没有解析,说明没有参数,即没有配置contructor-arg,为false,则使用默认的构造函数
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	// 如果是构造函数已经在缓存中存在了
	if (resolved) {
		// 如果是autowireNecessary为true,则说明需要使用非默认
		// 构造函数,即带有参数的构造函数,否则使用默认的构造函数
		if (autowireNecessary) {
			// <2021-03-22 16:46>
			// 通过带有参数的构造函数创建bean
			return autowireConstructor(beanName, mbd, null, null);
		}
		// 如果是构造函数参数还没有在缓存中,则说明
		// 是默认构造函数
		else {
			// <2021-03-22 16:47>
			// 调用默认构造函数创建bean
			return instantiateBean(beanName, mbd);
		}
	}

	// 执行到这里的话,说明调用的构造函数还没有确定
	// 这里需要确定要调用的目标构造函数
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		// 使用带有参数的构造函数创建bean
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// 使用带有参数的构造函数创建bean
	ctors = mbd.getPreferredConstructors();
	if (ctors != null) {
		return autowireConstructor(beanName, mbd, ctors, null);
	}

	// 使用无参数,即默认的构造函数创建bean
	return instantiateBean(beanName, mbd);
}

<2021-03-20 02:56>处是保证待实例化的bean是能够实例化的,其中Modifier.isPublic(beanClass.getModifiers())是判断class是否为public类型,源码如下:

java.lang.reflect.Modifier#isPublic
public static boolean isPublic(int mod) {
	// public static final int PUBLIC           = 0x00000001;
    return (mod & PUBLIC) != 0;
}

mbd.isNonPublicAccessAllowed()是返回是否允许访问非public的构造函数和方法,源码如下:

org.springframework.beans.factory.support.AbstractBeanDefinition#isNonPublicAccessAllowed
public boolean isNonPublicAccessAllowed() {
	// private boolean nonPublicAccessAllowed = true;
	// 该值默认为true,即允许访问
	return this.nonPublicAccessAllowed;
}

<2021-03-20 04:36>处尝试获取Supplier,通过Supplier获取对象,关于Supplier可以参考这里
,该处详细参考2.1:通过Supplier创建bean,<2021-03-20 05:21>处是通过factory-method来创建bean,关于factory-method可以参考这里,可以通过实例方法和静态方法来返回一个对象,该处详细参考2.2:通过factory-method创建bean<2021-03-22 16:46>处参考2.2:通过带有参数的构造函数创建bean<2021-03-22 16:47>处参考2.3:通过默认构造函数创建bean

2.1:通过Supplier创建bean

这里是在通过常规方式创建bean前尝试使用Supplier来创建对象,源码如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	...snip...
	// 获取Supplier
	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) {
		// <2021-03-20 04:43>
		return obtainFromSupplier(instanceSupplier, beanName);
	}
	...snip...
}

<2021-03-20 04:43>处源码如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#obtainFromSupplier
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
		Object instance;
	// private final NamedThreadLocal<String> currentlyCreatedBean 
	// = new NamedThreadLocal<>("Currently created bean");
	// 保留当前正在记录创建的bean名称,后续重新设置回去
	String outerBean = this.currentlyCreatedBean.get();
	// 设置当前创建的bean名称
	this.currentlyCreatedBean.set(beanName);
	try {
		// 通过Supplier的get方法获取实例对象
		instance = instanceSupplier.get();
	}
	finally {
		// 如果是原来的bean名称不为空,则重新设置回去,否则删除当前的
		if (outerBean != null) {
			this.currentlyCreatedBean.set(outerBean);
		}
		else {
			this.currentlyCreatedBean.remove();
		}
	}
	// 如果是返回的为null则使用NullBean
	if (instance == null) {
		instance = new NullBean();
	}
	// 封装到BeanWrapper中
	BeanWrapper bw = new BeanWrapperImpl(instance);
	// 初始化BeanWrapper,详细略
	initBeanWrapper(bw);
	return bw;
}

2.2:通过factory-method创建bean

源码:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	...snip...
	if (mbd.getFactoryMethodName() != null) {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	...snip...
	}
}

继续源码:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod
protected BeanWrapper instantiateUsingFactoryMethod(
			String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

	return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

创建了ConstructorResolver对象并调用器instantiateUsingFactoryMethod方法,源码如下:

org.springframework.beans.factory.support.ConstructorResolver#instantiateUsingFactoryMethod
public BeanWrapper instantiateUsingFactoryMethod(
		String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
	// 创建BeanWrapper对象
	BeanWrapperImpl bw = new BeanWrapperImpl();
	// 注册用于转换属性值的ConversionService和PropertyEditor
	// 参考:https://blog.csdn.net/wang0907/article/details/115043257
	// https://blog.csdn.net/wang0907/article/details/115046359
	this.beanFactory.initBeanWrapper(bw);
	
	// 用于创建对象的工厂bean
	Object factoryBean;
	// 工厂bean的class类型
	Class<?> factoryClass;
	// 是否是通过静态方法获取bean,true为是,fasle为不是
	boolean isStatic;
	// 工厂bean获取bean的方法有两种,一种是通过工厂的静态方法
	// 另外一种是通过工厂的实例方法,这里就是通过实例方法获取
	// 时工厂bean的名称
	String factoryBeanName = mbd.getFactoryBeanName();
	// 如果是工厂bean的名称不为空,则是工厂bean的实例方法获取bean
	if (factoryBeanName != null) { // 实例方法
		// 判断使用要创建的bean作为工厂bean的异常情况
		if (factoryBeanName.equals(beanName)) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
					"factory-bean reference points back to the same bean definition");
		}
		// 从bean工厂IOC容器中获取工厂bean
		factoryBean = this.beanFactory.getBean(factoryBeanName);
		// 没搞清楚这里要判断什么到底???
		if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
			throw new ImplicitlyAppearedSingletonException();
		}
		// 获取工厂bean的class类型
		factoryClass = factoryBean.getClass();
		// 标记为不是通过静态方法获取bean
		isStatic = false;
	}
	// 否则就是通过实例工厂的静态方法获取bean,此时不需要工厂的实例
	// 因为调用静态方法不需要实例对象
	else { // 静态方法
		// 判断是否设置了工厂类的class属性,因为要通过class调用其
		// 静态方法获取bean,所以这里必须指定,否则无法调用其静态方法
		if (!mbd.hasBeanClass()) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
					"bean definition declares neither a bean class nor a factory-bean reference");
		}
		// 因为是静态方法获取,所以就不需要工厂bean了
		factoryBean = null;
		// 设置工厂bean的class类型
		factoryClass = mbd.getBeanClass();
		// 标记为是通过工厂bean的静态方法获取bean
		isStatic = true;
	}

	Method factoryMethodToUse = null;
	ArgumentsHolder argsHolderToUse = null;
	Object[] argsToUse = null;
	// 开始获取调用工厂方法需要的入参信息
	// 如果是调用getBean时显示传入了参数,则直接使用作为
	// 调用工厂方法的入参
	if (explicitArgs != null) {
		argsToUse = explicitArgs;
	}
	// getBean没有显式指定的话,首先通过缓存获取
	// 缓存没有的话尝试从配置文件中解析
	else {
		Object[] argsToResolve = null;
		synchronized (mbd.constructorArgumentLock) {
			// 从缓存中获取目标方法对应的Method对象
			factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
			if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
				// 尝试从缓存中获取调用方法需要的参数数组信息
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					argsToResolve = mbd.preparedConstructorArguments;
				}
			}
		}
		if (argsToResolve != null) {
			argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
		}
	}
	// 过是
	if (factoryMethodToUse == null || argsToUse == null) {
		// 因为这里可能存在如cglib代理的情况,此时factoryClass的值
		// 是用户实际工厂类的子类,这里就是获取工厂类的实际类型
		factoryClass = ClassUtils.getUserClass(factoryClass);
		// 获取工厂类的所有的方法
		Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
		// 可能满足要求的工厂方法
		List<Method> candidateList = new ArrayList<>();
		for (Method candidate : rawCandidates) {
			// 从以下两个方面进行候选方法判断,注意包含了从父类继承而来的
			// 1:静态非静态是否和isStatic相同
			// 2:方法名称是否和工厂方法名称相同mbd.isFactoryMethod(candidate)
			// 如果是两者都满足的话,则有可能是需要调用的目标方法
			// 此时就差参数确定了
			if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
				candidateList.add(candidate);
			}
		}
		// 满足以下3个条件则为true
		// 1:候选方法只有1个,即唯一确定
		// 2:没有明确的传入参数,一定程度上说明方法不需要参数
		// 3:bd信息中没有配置参数(并不确定是方法真的不需要参数),则不需要后续的参数解析工作了
		// 此时就可以直接开始解析目标工厂方法,获取实例了
		if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
			// 获取唯一的方法
			Method uniqueCandidate = candidateList.get(0);
			// 如果是方法的参数个数为0,即方法确实不需要参数
			if (uniqueCandidate.getParameterCount() == 0) {
				// 设置用于内省的工厂方法到bd中
				mbd.factoryMethodToIntrospect = uniqueCandidate;
				synchronized (mbd.constructorArgumentLock) {
					// 设置解析出的工厂方法
					mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
					// 设置已经解析出工厂方法需要的参数
					mbd.constructorArgumentsResolved = true;
					// 设置解析出的工厂方法的参数为空参数
					// private static final Object[] EMPTY_ARGS = new Object[0];
					// 这里是为了和有参数的工厂方法的调用保持一致
					mbd.resolvedConstructorArguments = EMPTY_ARGS;
				}
				// <2021-03-21 21:04>
				// 通过instantiate方法创建bean并设置到bw中,然后返回
				bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
				return bw;
			}
		}
		// 将候选工厂方法转换为Method数组
		Method[] candidates = candidateList.toArray(new Method[0]);
		// <2021-03:22 09:58>
		// 先按照方法是否为public排序,然后按照参数个数排序
		AutowireUtils.sortFactoryMethods(candidates);
		// 承载解析出的方法参数值信息
		ConstructorArgumentValues resolvedValues = null;
		// 这里认为是false即可
		boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
		// 最小的匹配值,用于选择匹配度最高的一个工厂方法作为目标方法
		int minTypeDiffWeight = Integer.MAX_VALUE;
		// 可能为目标模板方法的方法集合
		Set<Method> ambiguousFactoryMethods = null;
		// 最小的参数的个数
		int minNrOfArgs;
		// 如果有传入的明确参数,则用其参数个数作为最小参数个数
		if (explicitArgs != null) {
			minNrOfArgs = explicitArgs.length;
		}
		// 没有明确的传入参数,正在会走这里
		else {
			// 如果是在xml文件中设置了参数
			if (mbd.hasConstructorArgumentValues()) {
				// 获取xml中设置的参数信息
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				// 定义封装最终解析出的参数值信息对象
				resolvedValues = new ConstructorArgumentValues();
				// 解析参数值信息,会涉及到其他bean,将结果
				// 放到resolveValues中,然后返回参数的个数
				// 作为最小的参数的个数
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}
			// 如果是没有则设置最小的参数的个数为0
			else {
				minNrOfArgs = 0;
			}
		}
		// 存储UnsatisfiedDependencyException异常的集合
		LinkedList<UnsatisfiedDependencyException> causes = null;
		// 遍历候选方法挨个处理
		for (Method candidate : candidates) {
			// 获取方法的参数类型数组
			Class<?>[] paramTypes = candidate.getParameterTypes();
			// 因为前面已经按照参数个数排序,这里>=minNrOfArgs
			// 的方法就是还没有进行处理的
			if (paramTypes.length >= minNrOfArgs) {
				// 存储参数的对象
				ArgumentsHolder argsHolder;
				// 如果有明确传入参数,则使用
				if (explicitArgs != null) {
					// 传入的参数个数必须和当前方法的参数个数完全一致
					// 否则continue,认为该方法不适合
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					argsHolder = new ArgumentsHolder(explicitArgs);
				}
				else {
					// Resolved constructor arguments: type conversion and/or autowiring necessary.
					try {
						// 参数名称数组
						String[] paramNames = null;
						// 从bean工厂中获取参数名称探测器
						ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
						// 如果是方法名称探测器不为空则用其
						// 从方法中提取参数名称数组信息
						if (pnd != null) {
							paramNames = pnd.getParameterNames(candidate);
						}
						// 创建参数持有者对象
						argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
								paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
					}
					catch (UnsatisfiedDependencyException ex) {
						if (logger.isTraceEnabled()) {
							logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
						}
						// Swallow and try next overloaded factory method.
						if (causes == null) {
							causes = new LinkedList<>();
						}
						// 发生UnsatisfiedDependency异常则添加
						causes.add(ex);
						// 继续下一个方法
						continue;
					}
				}
				// mbd.isLenientConstructorResolution()是否为宽松模式
				// 宽松模式:使用最接近的模式进行匹配
				// 非宽松模式/严格模式:个数的类型必须完全匹配
				// 最终获取一个当前方法参数和xml中配置的参数的
				// 相差的权重值,值越小匹配度越高
				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				// 如果是当前方法权重小于(优先级高于)当前的最小权重
				if (typeDiffWeight < minTypeDiffWeight) {
					// 设置当前方法为要使用的工厂方法
					factoryMethodToUse = candidate;
					// 设置当前参数拥有者为要使用的
					argsHolderToUse = argsHolder;
					// 设置要使用的参数
					argsToUse = argsHolder.arguments;
					// 重新赋值当前最小权重
					minTypeDiffWeight = typeDiffWeight;
					// 设置模糊工厂方法set集合为空
					ambiguousFactoryMethods = null;
				}
				// 满足以下条件:
				// 1:当前要使用的工厂发不为空
				// 2:当前放大权重和当前最小权重相同
				// 3:是严格模式
				// 4:真实参数个数和当前方法参数个数相同
				// 5:参数类型不是完全相同
				else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
						!mbd.isLenientConstructorResolution() &&
						paramTypes.length == factoryMethodToUse.getParameterCount() &&
						!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
					// 添加factoryMethodToUse即上一个(之前循环产生的)可能使用的工厂方法
					// 和当前候选方法到模糊工厂方法集合中
					if (ambiguousFactoryMethods == null) {
						ambiguousFactoryMethods = new LinkedHashSet<>();
						// 添加前面循环产生的可能使用的工厂方法
						ambiguousFactoryMethods.add(factoryMethodToUse);
					}
					// 添加当前的候选方法(也是可能使用的工厂方法)
					ambiguousFactoryMethods.add(candidate);
				}
			}
		}
		// 循环结束了,但是没有找到要使用的工厂方法,则异常
		if (factoryMethodToUse == null) {
			if (causes != null) {
				UnsatisfiedDependencyException ex = causes.removeLast();
				// 循环设置异常信息
				for (Exception cause : causes) {
					this.beanFactory.onSuppressedException(cause);
				}
				throw ex;
			}
			// 参数类型数组
			List<String> argTypes = new ArrayList<>(minNrOfArgs);
			// 封装异常需要的提示信息
			if (explicitArgs != null) {
				for (Object arg : explicitArgs) {
					argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
				}
			}
			else if (resolvedValues != null) {
				Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
				valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
				valueHolders.addAll(resolvedValues.getGenericArgumentValues());
				for (ValueHolder value : valueHolders) {
					String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
							(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
					argTypes.add(argType);
				}
			}
			String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"No matching factory method found: " +
					(mbd.getFactoryBeanName() != null ?
						"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
					"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
					"Check that a method with the specified name " +
					(minNrOfArgs > 0 ? "and arguments " : "") +
					"exists and that it is " +
					(isStatic ? "static" : "non-static") + ".");
		}
		// 如果是方法的返回类型是void,则异常
		// 因为要通过方法获取对象,所以不能为void
		else if (void.class == factoryMethodToUse.getReturnType()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Invalid factory method '" + mbd.getFactoryMethodName() +
					"': needs to have a non-void return type!");
		}
		// 如果是存在模糊工厂方法,则异常,因为这种情况下
		// 无法确定一个方法
		else if (ambiguousFactoryMethods != null) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Ambiguous factory method matches found in bean '" + beanName + "' " +
					"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
					ambiguousFactoryMethods);
		}
		// 缓存操作吧
		if (explicitArgs == null && argsHolderToUse != null) {
			mbd.factoryMethodToIntrospect = factoryMethodToUse;
			argsHolderToUse.storeCache(mbd, factoryMethodToUse);
		}
	}
	// 断言工厂方法要使用的参数不为null
	Assert.state(argsToUse != null, "Unresolved factory method arguments");
	// <2021-03-22 14:44>
	bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
	return bw;
}

<2021-03-21 21:04>处是通过工厂bean方法创建bean,详细参考2.2.1:instantiate创建bean<2021-03:22 09:58>处是对方法进行排序,源码如下:

org.springframework.beans.factory.support.AutowireUtils#sortFactoryMethods
public static void sortFactoryMethods(Method[] factoryMethods) {
	Arrays.sort(factoryMethods, EXECUTABLE_COMPARATOR);
}

看下EXECUTABLE_COMPARATOR,源码如下:

org.springframework.beans.factory.support.AutowireUtils#EXECUTABLE_COMPARATOR
private static final Comparator<Executable> EXECUTABLE_COMPARATOR = (e1, e2) -> {
	boolean p1 = Modifier.isPublic(e1.getModifiers());
	boolean p2 = Modifier.isPublic(e2.getModifiers());
	// 如果一个是public,一个不是public则是public
	// 的把public的排在前面
	if (p1 != p2) {
		return (p1 ? -1 : 1);
	}
	// 如果方法访问权限修饰符相同,则根据方法的参数的个数排序,多的排在前面
	int c1pl = e1.getParameterCount();
	int c2pl = e2.getParameterCount();
	return Integer.compare(c2pl, c1pl);
};

<2021-03-22 14:44>处是调用工厂方法创建bean,详细参考2.2.1:instantiate创建bean

2.2.1:instantiate创建bean

到这里的话,通过工厂方法所需要的工厂bean,工厂bean的工厂方法,调用工厂方法所需要的参数都已经确定完毕了,剩下的就是调用factory-bean的factory-method方法获取bean了。
源码如下:

org.springframework.beans.factory.support.ConstructorResolver#instantiate(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
private Object instantiate(String beanName, RootBeanDefinition mbd,
			@Nullable Object factoryBean, Method factoryMethod, Object[] args) {

	try{
		// <2021-03-22 09:05>
		if (System.getSecurityManager() != null) {
			return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
					this.beanFactory.getInstantiationStrategy().instantiate(
							mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args),
					this.beanFactory.getAccessControlContext());
		}
		else {
			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);
	}
}

<2021-03-22 09:05>处不管是否需要安全认证,最终都是执行代码this.beanFactory.getInstantiationStrategy().instantiate,因此我们只需要看下这里的代码就可以了,源码如下:

org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory, java.lang.Object, java.lang.reflect.Method, java.lang.Object...)
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			@Nullable Object factoryBean, final Method factoryMethod, Object... args) {

	try {
		// 设置factory-method对应的method对象可访问
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				ReflectionUtils.makeAccessible(factoryMethod);
				return null;
			});
		}
		else {
			ReflectionUtils.makeAccessible(factoryMethod);
		}
		// 从threadlocal中获取当前正在执行的工厂方法
		Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
		try {
			// 设置正在执行的工厂方法为当前方法
			currentlyInvokedFactoryMethod.set(factoryMethod);
			// 反射执行返回,获取对象
			Object result = factoryMethod.invoke(factoryBean, args);
			// 如果是返回的对象为null,则使用NullBean
			if (result == null) {
				result = new NullBean();
			}
			// 返回结果
			return result;
		}
		finally {
			// 如果是之前正在执行的工厂方法不为null,
			// 则重新设置回去,否则直接删除当前的
			if (priorInvokedFactoryMethod != null) {
				currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
			}
			else {
				currentlyInvokedFactoryMethod.remove();
			}
		}
	}
	catch (IllegalArgumentException ex) { // 参数错误异常
		throw new BeanInstantiationException(factoryMethod,
				"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
				"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
	}
	catch (IllegalAccessException ex) { // 方法访问异常
		throw new BeanInstantiationException(factoryMethod,
				"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
	}
	catch (InvocationTargetException ex) {
		String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
		if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
				((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
			msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
					"declaring the factory method as static for independence from its containing instance. " + msg;
		}
		throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());
	}
}

2.2:通过带有参数构造函数创建bean

此处是通过带有参数的构造函数来创建bean,源码如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireConstructor
protected BeanWrapper autowireConstructor(
			String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

	return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

继续:

org.springframework.beans.factory.support.ConstructorResolver#autowireConstructor
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
			@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
	// 定义wrapper
	BeanWrapperImpl bw = new BeanWrapperImpl();
	// 设置用于数据类型转换的ConversionService和
	this.beanFactory.initBeanWrapper(bw);
	
	// 要使用的构造函数
	Constructor<?> constructorToUse = null;
	// 要使用的构造函数参数封装对象
	ArgumentsHolder argsHolderToUse = null;
	// 最终用来调用构造函数的参数数组
	Object[] argsToUse = null;
	// 如果是现实传入的参数不为空,则使用传入的参数
	if (explicitArgs != null) {
		argsToUse = explicitArgs;
	}
	// 解析
	else {
		// 解析出的参数
		Object[] argsToResolve = null;
		synchronized (mbd.constructorArgumentLock) {
			// 尝试获取缓存的构造函数方法
			constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
			// 如果是缓存中有,并且构造函数函数参数也解析出来了
			if (constructorToUse != null && mbd.constructorArgumentsResolved) {
				// 尝试从缓存中获取构造函数需要的参数
				argsToUse = mbd.resolvedConstructorArguments;
				// 如果是缓存中不存在构造函数使用的参数
				if (argsToUse == null) {
					// 如果是缓存为空,则使用在db中准备的参数(此时的参数一般都是字符串,还不可以直接用来调用构造函数)
					argsToResolve = mbd.preparedConstructorArguments;
				}
			}
		}
		// argsToResolve值可能是("1","1"),但是构造函数需要的是(1,1)
		// 这里就是进行转换为构造函数可用的参数,然后赋值到argsToUse的Object数组对象
		if (argsToResolve != null) {
			argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
		}
	}
	// 如果是构造函数和构造函数要使用的参数都没有解析出来
	if (constructorToUse == null || argsToUse == null) {
		// 先将传入的待选择的构造函数作为候选构造函数
		Constructor<?>[] candidates = chosenCtors;
		// 如果是候选构造函数为null
		if (candidates == null) {
			// 获取bean的class类型
			Class<?> beanClass = mbd.getBeanClass();
			try {
				// 获取所有的构造函数作为候选构造函数
				candidates = (mbd.isNonPublicAccessAllowed() ?
						beanClass.getDeclaredConstructors() : beanClass.getConstructors());
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Resolution of declared constructors on bean Class [" + beanClass.getName() +
						"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
			}
		}
		// 处理只有一个构造函数且构造函数没有参数情况的初始化
		if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
			Constructor<?> uniqueCandidate = candidates[0];
			if (uniqueCandidate.getParameterCount() == 0) {
				synchronized (mbd.constructorArgumentLock) {
					mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
					mbd.constructorArgumentsResolved = true;
					mbd.resolvedConstructorArguments = EMPTY_ARGS;
				}
				// 初始化,参考2.2.1:instantiate创建bean
				bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
				return bw;
			}
		}

		// 是否需要解析构造函数
		boolean autowiring = (chosenCtors != null ||
				mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
		ConstructorArgumentValues resolvedValues = null;
		// 构造函数参数的最小个数
		int minNrOfArgs;
		// 传入参数不为空,使用传入参数的个数作为当前最小个数
		if (explicitArgs != null) {
			minNrOfArgs = explicitArgs.length;
		}
		else {
			// 从bd中解析参数
			ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
			// 存储参数的对象
			resolvedValues = new ConstructorArgumentValues();
			// 存储参数到resolvedValues并返回参数的个数作为当掐你最小参数个数
			minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
		}
		// 按照public,非public,参数个数排序
		AutowireUtils.sortConstructors(candidates);
		// 权重,值越小优先级越大
		int minTypeDiffWeight = Integer.MAX_VALUE;
		Set<Constructor<?>> ambiguousConstructors = null;
		LinkedList<UnsatisfiedDependencyException> causes = null;
		// 循环候选构造函数,找到权重最大的作为目标构造函数
		for (Constructor<?> candidate : candidates) {
			// 获取参数类型
			Class<?>[] paramTypes = candidate.getParameterTypes();
			// 期望的参数个数大于当前参数个数的直接break,这里break的原因
			// 是已经按照参数从大到小排序了,后面的参数个数不会变多
			if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
				break;
			}
			if (paramTypes.length < minNrOfArgs) {
				continue;
			}
			// 存储参数的对象
			ArgumentsHolder argsHolder;
			if (resolvedValues != null) {
				try {
					// 解析参数的名称
					String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
					// 为空则从bd中获取
					if (paramNames == null) {
						ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
						if (pnd != null) {
							paramNames = pnd.getParameterNames(candidate);
						}
					}
					argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
							getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
				}
				catch (UnsatisfiedDependencyException ex) {
					if (logger.isTraceEnabled()) {
						logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
					}
					// Swallow and try next constructor.
					if (causes == null) {
						causes = new LinkedList<>();
					}
					causes.add(ex);
					continue;
				}
			}
			else {
				// Explicit arguments given -> arguments length must match exactly.
				if (paramTypes.length != explicitArgs.length) {
					continue;
				}
				argsHolder = new ArgumentsHolder(explicitArgs);
			}

			int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
					argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
			// Choose this constructor if it represents the closest match.
			if (typeDiffWeight < minTypeDiffWeight) {
				constructorToUse = candidate;
				argsHolderToUse = argsHolder;
				argsToUse = argsHolder.arguments;
				minTypeDiffWeight = typeDiffWeight;
				ambiguousConstructors = null;
			}
			else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
				if (ambiguousConstructors == null) {
					ambiguousConstructors = new LinkedHashSet<>();
					ambiguousConstructors.add(constructorToUse);
				}
				ambiguousConstructors.add(candidate);
			}
		}
		// 如果是没有找到可用的构造函数,则异常
		if (constructorToUse == null) {
			if (causes != null) {
				UnsatisfiedDependencyException ex = causes.removeLast();
				for (Exception cause : causes) {
					this.beanFactory.onSuppressedException(cause);
				}
				throw ex;
			}
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Could not resolve matching constructor " +
					"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
		}
		// 存在模糊构造函数,此时无法确定具体是哪个,异常
		else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Ambiguous constructor matches found in bean '" + beanName + "' " +
					"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
					ambiguousConstructors);
		}
		// 将构造函数和构造函数的擦书放到缓存中
		if (explicitArgs == null && argsHolderToUse != null) {
			argsHolderToUse.storeCache(mbd, constructorToUse);
		}
	}

	Assert.state(argsToUse != null, "Unresolved constructor arguments");
	// <2021-03-24 17:15>
	bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
	return bw;
}

<2021-03-24 17:15>处是通过构造函数的方法创建bean,具体参考2.2.1:通过带有参数构造函数创建bean

2.2.1:通过带有参数构造函数创建bean

这里是通过带有参数的构造函数,以及其构造函数参数来创建bean,源码如下:

org.springframework.beans.factory.support.ConstructorResolver#instantiate(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.reflect.Constructor<?>, java.lang.Object[])
private Object instantiate(
			String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) {
	try {
		// 获取初始化策略器
		InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
		if (System.getSecurityManager() != null) {
			return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
					strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
					this.beanFactory.getAccessControlContext());
		}
		else {
			// <2021-03-24 17:26>
			return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean instantiation via constructor failed", ex);
	}
}

<2021-03-24 17:26>处源码如下:

org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory, java.lang.reflect.Constructor<?>, java.lang.Object...)
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			final Constructor<?> ctor, Object... args) {
	// 如果是没有配置lookup-method,replace-method
	// 则说明当前的bean不需要额外处理,直接创建接口
	if (!bd.hasMethodOverrides()) {
		if (System.getSecurityManager() != null) {
			// use own privileged to change accessibility (when security is on)
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				ReflectionUtils.makeAccessible(ctor);
				return null;
			});
		}
		// 不需要额外处理,直接反射创建bean
		return BeanUtils.instantiateClass(ctor, args);
	}
	// 否则需要额外处理,此时需要生成代理bean
	else {
		// <2021-03-24 17:39>
		// 通过CGLIB生成代理bean
		return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
	}
}

<2021-03-24 17:39>处参考2.2.2:通过CGLIB生成代理bean

2.2.2:通过CGLIB生成代理bean

该处是通过CGLIB生成代理bean,源码如下:

org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy#instantiateWithMethodInjection(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory, java.lang.reflect.Constructor<?>, java.lang.Object...)
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			@Nullable Constructor<?> ctor, Object... args) {

	// Must generate CGLIB subclass...
	return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}

继续:

org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy.CglibSubclassCreator#instantiate
public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
	// 通过bd生成子类的class对象
	Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
	Object instance;
	// 没有构造器则使用默认构造器创建
	if (ctor == null) {
		instance = BeanUtils.instantiateClass(subclass);
	}
	// 存在构造器
	else {
		try {
			// 通过参数类型,获取cglib动态生成的子类的对应的构造函数
			Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
			// 通过构造函数创建实例
			instance = enhancedSubclassConstructor.newInstance(args);
		}
		catch (Exception ex) {
			throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
					"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
		}
	}
	// 设置回调???
	Factory factory = (Factory) instance;
	factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
			new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
			new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
	return instance;
}

2.3:通过默认构造函数创建bean

此处是通过默认构造函数来创建bean,源码如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
	try {
		Object beanInstance;
		final BeanFactory parent = this;
		// 是否需要安全校验
		if (System.getSecurityManager() != null) {
			beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
					getInstantiationStrategy().instantiate(mbd, beanName, parent),
					getAccessControlContext());
		}
		else {
			// <2021-03-24 17:57>
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
		}
		// 封装到wrapper中
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		initBeanWrapper(bw);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	}
}

<2021-03-24 17:57>处是通过默认构造函数创建bean,源码如下:

org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
	// 如果没有设置lookup-method,replaced-method
	// 则直接创建,不需要生成代理
	if (!bd.hasMethodOverrides()) {
		Constructor<?> constructorToUse;
		synchronized (bd.constructorArgumentLock) {
			constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
			if (constructorToUse == null) {
				final Class<?> clazz = bd.getBeanClass();
				if (clazz.isInterface()) {
					throw new BeanInstantiationException(clazz, "Specified class is an interface");
				}
				try {
					if (System.getSecurityManager() != null) {
						constructorToUse = AccessController.doPrivileged(
								(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
					}
					else {
						// 获取没有参数的构造函数
						constructorToUse = clazz.getDeclaredConstructor();
					}
					// 将构造函数赋值都bd中
					bd.resolvedConstructorOrFactoryMethod = constructorToUse;
				}
				catch (Throwable ex) {
					throw new BeanInstantiationException(clazz, "No default constructor found", ex);
				}
			}
		}
		// 反射创建bean
		return BeanUtils.instantiateClass(constructorToUse);
	}
	else {
		// 使用CGLIB生成子类,即代理类
		return instantiateWithMethodInjection(bd, beanName, owner);
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值