春の5.xのソース・旅行二十から五getBean詳細な10-argのコンストラクタ自動組立autowireConstructor
自動組立構成autowireConstructor方法
また、内部呼び出すConstructorResolver
方法を。
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
ConstructorResolver的autowireConstructor
これとリコールファクトリメソッドは、インスタンス化するinstantiateUsingFactoryMethod
ように、いくつかの場所が同じでありませんされています。
- ファクトリメソッドは、フィニッシュまでずっと横断し、次に最小差分法パラメータタイプを見つけ、自動組立工法条件を満足停止見つけることであろう。
- アルゴリズムを差分パラメータタイプが同じではない、ファクトリメソッドは、厳密な方法であり
getAssignabilityWeight
、自動組立方法が緩んでいますgetTypeDifferenceWeight
。
ConstructorResolver的getTypeDifferenceWeight
ためにも価値の違いにより、優先順位の元の型と、元の違いのパラメータの型とパラメータの型を取得しますが、それでも-1024.
//获取类型差异值
public int getTypeDifferenceWeight(Class<?>[] paramTypes) {
//找出参数类型,和原始参数类型的差异,选最小的
int typeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.arguments);
int rawTypeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.rawArguments) - 1024;
return Math.min(rawTypeDiffWeight, typeDiffWeight);
}
MethodInvoker的getTypeDifferenceWeight
ここでパラメータ・タイプ定義型と継承されない場合、受信パラメータを比較する方法であり、直接の親クラス・タイプは、パラメータタイプ、差がある場合、それは、取得された、親受信パラメータを継承している場合、最大の差を返し+2
、さもなければ、その後、差があり、親クラスの型はtypeパラメータのサブクラスであるかどうかを確認+2
した後、これまでに無い親になるまで、親クラスの親を探し続け、最後のパラメータは、あなたが違いを見つけた場合のインターフェイスタイプで+1
、その後、違いを返します。
public static int getTypeDifferenceWeight(Class<?>[] paramTypes, Object[] args) {
int result = 0;
for (int i = 0; i < paramTypes.length; i++) {
if (!ClassUtils.isAssignableValue(paramTypes[i], args[i])) {
return Integer.MAX_VALUE;//有参数类型不匹配直接返回最大差异
}
if (args[i] != null) {
Class<?> paramType = paramTypes[i];
Class<?> superClass = args[i].getClass().getSuperclass();//获得传入参数的父类来比较
while (superClass != null) {
if (paramType.equals(superClass)) {//参数类型等于父类型的,差异+2
result = result + 2;
superClass = null;
}
else if (ClassUtils.isAssignable(paramType, superClass)) {//superClass是paramType的子类类型,差异+2,可能还有paramType的子类类型,再尝试获取
result = result + 2;
superClass = superClass.getSuperclass();
}
else {
superClass = null;
}
}
if (paramType.isInterface()) {//参数类型是接口类型,差异+1
result = result + 1;
}
}
}
return result;
}
比較は、同じタイプ、またはサブクラスのものであるかどうかisAssignableのClassUtils
クラス、すなわち、同じまたはサブクラスではない2つの主なクラスの比較はrhsType
ないlhsType
サブクラスまたは類似。
public static boolean isAssignable(Class<?> lhsType, Class<?> rhsType) {
Assert.notNull(lhsType, "Left-hand side type must not be null");
Assert.notNull(rhsType, "Right-hand side type must not be null");
if (lhsType.isAssignableFrom(rhsType)) {
return true;
}
if (lhsType.isPrimitive()) {
Class<?> resolvedPrimitive = primitiveWrapperTypeMap.get(rhsType);
if (lhsType == resolvedPrimitive) {
return true;
}
}
else {
Class<?> resolvedWrapper = primitiveTypeToWrapperMap.get(rhsType);
if (resolvedWrapper != null && lhsType.isAssignableFrom(resolvedWrapper)) {
return true;
}
}
return false;
}
クラス的isAssignableFrom
a.isAssignableFrom(b)
、それはb
ないですa
同じ種類またはサブクラス。
さて、今日ここに、私たちは自分自身の学習、限られた容量を理解し、偉大な神は見スプレーしないで、言い訳してください、助けの調査に希望と理解しています。