Spring源码:工厂方法实例化Bean
程序员文章站
2022-05-21 22:55:09
...
源代码
该函数在类ConstructorResolver(该类的作用:构造函数和工厂方法解析的代理,主要作用通过参数匹配执行构造函数解析)为了简化分析,去除了不必要的异常和日志。
public BeanWrapper instantiateUsingFactoryMethod(final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
// 把BeanFactory的框架内置和自定义PropertyEditor放到BeanWrapperImpl中
this.beanFactory.initBeanWrapper(bw);
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
// 第一部分:获取工厂类class、工厂类方法、参数
String factoryBeanName = mbd.getFactoryBeanName();
if (factoryBeanName != null) {
// 加载标签factory-bean指向的class,一般说含有factory-bean标签时,其指向的class是非静态
factoryBean = this.beanFactory.getBean(factoryBeanName);
factoryClass = factoryBean.getClass();
isStatic = false;
} else {
// 不含有factory-bean标签,工厂Bean含有创建Bean的静态方法
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
// 若getBean方法调用时指定了方法参数,则直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
} else {
// 若getBean方法调用时没有指定方法参数,则尝试从配置文件中加载
Object[] argsToResolve = null;
// 对mbd的构造函数加锁
synchronized (mbd.constructorArgumentLock) {
// 从缓存中取构造函数或工厂方法
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);
}
}
// 第二部分:
// 若没有被缓存的构造函数或工厂方法,且参数也无法获取,重新分析
if (factoryMethodToUse == null || argsToUse == null) {
factoryClass = ClassUtils.getUserClass(factoryClass);
// 根据mdb的nonPublicAccessAllowed字段获取候选的方法集合rawCandidates
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
// 对 rawCandidates 集合进一步筛选与工厂方法名相同的的方法集合candidateSet
List<Method> candidateSet = new ArrayList<Method>();
for (Method candidate : rawCandidates) {
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidateSet.add(candidate);
}
}
Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]);
/**
** 对给定的工厂方法进行排序
** 先公共方法,再对公共方法参数递减排序
** 再私有方法,再对私有方法参数递减排序
**/
AutowireUtils.sortFactoryMethods(candidates);
ConstructorArgumentValues resolvedValues = null;
boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
} else {
// 提取配置文件中的配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
// 能解析到的参数个数(参考分析2)
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Method candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
// 若匹配到的方法的参数个数大于等于配置文件配置的参数个数
if (paramTypes.length >= minNrOfArgs) {
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
String[] paramNames = null;
// 获取参数名称解析器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 解析candidate方法中的参数
paramNames = pnd.getParameterNames(candidate);
}
// 给定已解析的构造函数参数值,创建一个参数数组来调用构造函数或工厂方法
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
} 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 factory method if it represents the closest match.
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.getParameterTypes().length && !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<Method>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
} //for (Method candidate : candidates)
if (factoryMethodToUse == null) {
// 抛出异常,没有找到对应的工厂方法
} else if (void.class == factoryMethodToUse.getReturnType()) {
// 抛出异常,需要返回值
} else if (ambiguousFactoryMethods != null) {
// 抛出异常,模糊的工厂方法与bean中匹配了
}
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
//
Object beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
if (beanInstance == null) {
return null;
}
bw.setBeanInstance(beanInstance);
return bw;
}
分析:
-
RootBeanDefinition的几个属性
//缓存已解析的构造函数或工厂方法 Object resolvedConstructorOrFactoryMethod; // 将构造函数参数标记为是否已解析 boolean constructorArgumentsResolved = false; // 缓存完全解析的构造函数参数 Object[] resolvedConstructorArguments; // 缓存部分准备好的构造函数参数,即配置文件中配置的参数 Object[] preparedConstructorArguments;
-
解析配置文件中的参数函数resolveConstructorArguments,该函数在类ConstructorResolver中,
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) { // 获取类型转换器 TypeConverter customConverter = this.beanFactory.getCustomTypeConverter(); TypeConverter converter = (customConverter != null ? customConverter : bw); BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter); // 配置文件中参数的个数 int minNrOfArgs = cargs.getArgumentCount(); for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) { // TODO int index = entry.getKey(); if (index > minNrOfArgs) { minNrOfArgs = index + 1; } ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue(); if (valueHolder.isConverted()) { // 若已经转换过 resolvedValues.addIndexedArgumentValue(index, valueHolder); } else { // 没有转换过 // BeanDefinitionValueResolver类resolveValueIfNecessary方法,主要解析Array,Set,Map,props和字符串类型的间接引用 Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName()); resolvedValueHolder.setSource(valueHolder); resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder); } } for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) { if (valueHolder.isConverted()) { resolvedValues.addGenericArgumentValue(valueHolder); } else { Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName()); resolvedValueHolder.setSource(valueHolder); resolvedValues.addGenericArgumentValue(resolvedValueHolder); } } return minNrOfArgs; }
-
实例化Bean,该方法在SimpleInstantiationStrategy类中,通过反射调用
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, Object factoryBean, final Method factoryMethod, Object... args) { ReflectionUtils.makeAccessible(factoryMethod); Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get(); try { currentlyInvokedFactoryMethod.set(factoryMethod); return factoryMethod.invoke(factoryBean, args); } finally { if (priorInvokedFactoryMethod != null) { currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod); } else { currentlyInvokedFactoryMethod.remove(); } } // finally }