spring(三)ConstructorResolver

本文详细介绍了Spring框架中ConstructorResolver的使用,包括instantiateUsingFactoryMethod、autowireConstructor等关键步骤。内容涵盖确定工厂对象、解析构造参数、实例化过程,以及不同构造方法参数的解析和处理。通过对这些方法的深入理解,可以更好地掌握Spring Bean的构造注入和工厂方法实例化机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ConstructorResolver

instantiateUsingFactoryMethod

在实例化bean的时候,如果判断需要使用工厂方法来实例化bean,那么就会调用ConstructorResolver的instantiateUsingFactoryMethod方法来进行实例化

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

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

这个方法比较长,所以分为多个部分看

确定工厂对象

// ConstructorResolver
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);

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

String factoryBeanName = mbd.getFactoryBeanName();
if (factoryBeanName != null) {
   
   
	// <1> 当前bean设置了factoryBeanName属性
	// 如果factoryBeanName和当前bean相同,那么直接报错
	if (factoryBeanName.equals(beanName)) {
   
   
		throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
				"factory-bean reference points back to the same bean definition");
	}
	// 从缓存中获取factory bean
	factoryBean = this.beanFactory.getBean(factoryBeanName);
	// 当前容器中已经存在需要创建的bean,报错
	if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
   
   
		throw new ImplicitlyAppearedSingletonException();
	}
	// 注册bean之间的依赖关系,当前创建的bean会依赖factorybeawn
	this.beanFactory.registerDependentBean(factoryBeanName, beanName);
	factoryClass = factoryBean.getClass();
	// 使用的不是静态方法
	isStatic = false;
}
else {
   
   
	// <2> 当前bean没有设置factoryBeanName
	// It's a static factory method on the bean class.
	if (!mbd.hasBeanClass()) {
   
   
		throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
				"bean definition declares neither a bean class nor a factory-bean reference");
	}
	factoryBean = null;
	// 工厂类是当前bean的类型
	factoryClass = mbd.getBeanClass();
	// 使用的是当前bean类型的静态工厂方法
	isStatic = true;
}

确认构造参数

// ConstructorResolver
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;

if (explicitArgs != null) {
   
   
	// <1> 如果在调用getBean方法时传入了参数,那么就确定使用该参数
	argsToUse = explicitArgs;
}
else {
   
   
	Object[] argsToResolve = null;
	synchronized (mbd.constructorArgumentLock) {
   
   
		// <2> 从缓存中获取,这些缓存的结果是在之后的代码中解析的,使用缓存避免重复解析
		// 获取缓存中的构造方法或者工厂方法
		factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
		if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
   
   
			// Found a cached factory method...
			// 从缓存中获取使用的参数
			argsToUse = mbd.resolvedConstructorArguments;
			if (argsToUse == null) {
   
   
				// 获取缓存中的包可见字段
				argsToResolve = mbd.preparedConstructorArguments;
			}
		}
	}
	if (argsToResolve != null) {
   
   
		// 对参数值进一步转换
		argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
	}
}

确定工厂方法和解析参数

// ConstructorResolver
factoryClass = ClassUtils.getUserClass(factoryClass);

List<Method> candidates = null;
if (mbd.isFactoryMethodUnique) {
   
   
	// <1> 如果bean的factoryMethod唯一,那么直接使用对应的方法作为候选方法
	if (factoryMethodToUse == null) {
   
   
		factoryMethodToUse = mbd.getResolvedFactoryMethod();
	}
	if (factoryMethodToUse != null) {
   
   
		candidates = Collections.singletonList(factoryMethodToUse);
	}
}
if (candidates == null) {
   
   
	// <2> bean没有指定有效的factoryMethod,开始寻找候选的工厂方法
	candidates = new ArrayList<>();
	// 遍历工厂类的所有方法
	// 然后进行过滤
	// 首先过滤掉方法名不同的候选方法
	// 然后,如果调用的是静态工厂方法,那么会过滤掉非静态方法;如果是普通工厂方法,那么会过滤掉静态方法
	Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
	for (Method candidate : rawCandidates) {
   
   
		if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
   
   
			candidates.add(candidate);
		}
	}
}

// <3> 如果只有一个候选方法,那么使用该方法创建bean
if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
   
   
	Method uniqueCandidate = candidates.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;
	}
}

// <4> 如果有多个候选方法,那么进行排序
// 首先按照是否public进行排序,public的排在前面
// 然后按照参数个数进行排序,参数多的排在前面
if (candidates.size() > 1) {
   
     // explicitly skip immutable singletonList
	candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
}

ConstructorArgumentValues resolvedValues = null;
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null;

// <5> 下面计算参数的个数
int minNrOfArgs;
if (explicitArgs != null) {
   
   
	// 如果显式指定了使用的参数,那么直接使用该参数的长度
	minNrOfArgs = explicitArgs.length;
}
else {
   
   
	// We don't have arguments passed in programmatically, so we need to resolve the
	// arguments specified in the constructor arguments held in the bean definition.
	// 没有显式地指定使用的参数,此时会使用指定的构造参数
	if (mbd.hasConstructorArgumentValues()) {
   
   
		ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
		resolvedValues = new ConstructorArgumentValues();
		// 对构造参数进行转换,并且返回参数的个数
		minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
	}
	else {
   
   
		minNrOfArgs = 0;
	}
}

Deque<UnsatisfiedDependencyException> causes = null;

// 遍历候选方法
for (Method candidate : candidates) {
   
   
	int parameterCount = candidate.getParameterCount();

	if (parameterCount >= minNrOfArgs) {
   
   
		ArgumentsHolder argsHolder;

		Class<?>[] paramTypes = candidate.getParameterTypes();
		// 如果显式指定了使用的参数,则候选方法的参数个数和显式参数的个数必须一致
		if (explicitArgs != null) {
   
   
			// Explicit arguments given -> arguments length must match exactly.
			if (paramTypes.length != explicitArgs.length) {
   
   
				continue;
			}
			argsHolder = new ArgumentsHolder(explicitArgs);
		}
		else {
   
   
			// Resolved constructor arguments: type conversion and/or autowiring necessary.
			try {
   
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值