class ConstructorResolver {
// 实例化普通类
private Object instantiate(String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) {
// private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
// 默认的实例化策略是CglibSubclassingInstantiationStrategy
return this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse)
{
// 如果没有方法覆盖的情况,只有@Looup,或者xml中配置了方法覆盖的情况下,才不为空
if (!bd.hasMethodOverrides()) {
// 通过构造方法反射创建对象
return BeanUtils.instantiateClass(ctor, args);
} else {
// 使用
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args) {
// 新建Cglib子类生成器
CglibSubclassCreator creator = new CglibSubclassCreator(bd, owner);
// 实例化子类对象
return creator.instantiate(ctor, args) {
// 创建CGLIB子类的Class对象
Class<?> subclass = createEnhancedSubclass(this.beanDefinition) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanDefinition.getBeanClass());
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
if (this.owner instanceof ConfigurableBeanFactory) {
ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
}
// 设置过滤器,在内部可以按照条件指定执行某一个Callback
// 因为Callback可以给定多个
enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
// 限制回调的类型
enhancer.setCallbackTypes(CALLBACK_TYPES);
// 创建子类
return enhancer.createClass();
}
Object instance;
if (ctor == null) {
// 反射实例化对象,使用默认的构造方法
instance = BeanUtils.instantiateClass(subclass);
} else {
// 如果有指定参数的构造方法
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
// 使用指定参数创建对象
instance = enhancedSubclassConstructor.newInstance(args);
}
// 生成的实例都是Factory的实例
Factory factory = (Factory) instance;
// 设置回调接口
factory.setCallbacks(new Callback[]{NoOp.INSTANCE,
// 处理@Lookup方法或者xml lookup方法的代理对象拦截器
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
// 处理xml中relace配置
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
}
}
}
}
// 实例化@Bean方法返回的对象
private Object instantiate(String beanName, RootBeanDefinition mbd, Object factoryBean, Method factoryMethod, Object[] args) {
return this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args)
{
// 反射执行方法
ReflectionUtils.makeAccessible(factoryMethod);
Object result = factoryMethod.invoke(factoryBean, args);
return result;
}
}
/**
* 构造注入
* @param explicitArgs 构造方法参数
*/
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, Constructor<?>[] chosenCtors, Object[] explicitArgs) {
// 创建BeanWrapperImpl
BeanWrapperImpl bw = new BeanWrapperImpl();
// 并初始化类型转换器
this.beanFactory.initBeanWrapper(bw);
// 需要使用的构造方法
Constructor<?> constructorToUse = null;
// 所有的构造函数参数集合
ArgumentsHolder argsHolderToUse = null;
// 需要使用的参数集合
Object[] argsToUse = null;
// 如果给定了参数,直接使用给定的参数实例化
if (explicitArgs != null) {
argsToUse = explicitArgs;
} else {
// 需要解析的参数
Object[] argsToResolve = null;
// 这里目的就是获取已经处理过一次Bean对象的缓存信息
synchronized (mbd.constructorArgumentLock) {
// 获取解析过的构造方法或者@Bean方法
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 如果之前就缓存解析好了构造方法,并且标记做了标记,已经被处理好
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// 缓存时候存入的
// if (ArgumentsHolder.resolveNecessary) {
// mbd.preparedConstructorArguments = this.preparedArguments;
// }
// else {
// mbd.resolvedConstructorArguments = this.arguments;
// }
// 找到已经处理好的缓存的构造函数参数,要不在resolvedConstructorArguments,要不在preparedConstructorArguments中
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果argsToResolve没有,表示构造函数从来没有处理过,没有被缓存
if (argsToResolve != null) {
// 提前解析构造参数,详见下面resolvePreparedArguments方法解析
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true) ''
}
}
// 如果当前Bean的构造方法没有被缓存,或者该构造方法的参数没有被解析
if (constructorToUse == null || argsToUse == null) {
// 获取指定的构造函数
Constructor<?>[] candidates = chosenCtors;
// 如果没有传递指定的构造方法
if (candidates == null) {
// 获取类型
Class<?> beanClass = mbd.getBeanClass();
// 如果允许访问非public的构造方法,就获取所有的的,否则只获取public的构造方法
candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
// 如果只有一个构造方法,并且也没有指定参数,并且没有手动对BD设置构造参数
// 因为这种条件最简单,也不需要对构造函数的参数进行解析,类型转换啥的
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
// 就使用这个构造方法
Constructor<?> uniqueCandidate = candidates[0];
// 如果是无参构造
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
// 缓存解析后的构造函数
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
// 标记该Bean的构造参数已经解析完成了
mbd.constructorArgumentsResolved = true;
// 缓存已经解析好的构造参数,就是一个空数组
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
// 实例化,并保存到BeanWrapper中,实例化过程详见上面的instantiate方法,四个参数的
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
// 返回包装好的对象
return bw;
}
}
// 需要解析构造函数
// 如果参数传递指定的构造函数,或者BD中设置了注入模式为构造注入,这个时候就需要使用构造注入
// 只有两种情况会指定构造函数
// 1. 只有当SmartInstantiationAwareBeanPostProcessor,determineConstructorsFromBeanPostProcessors后置处理器返回了指定要用的构造函数
// 2. 在BD中,有重写getPreferredConstructors方法,并返回给定的构造函数
// 其他情况,构造方法都是空的
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();
// 解析构造参数值,详见下面resolveConstructorArguments,并返回可用构造函数的最小参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 对可用的构造函数进行排序
AutowireUtils.sortConstructors(candidates);
// 遍历说中可用的构造方法
for (Constructor<?> candidate : candidates) {
// 获取参数个数
int parameterCount = candidate.getParameterCount();
// 如果已经有可用的方法,并且也有对应的可用参数,并且参数的个数可用的参数比实际的参数多
// 表示这个构造方法已经可以用了,就不需要再找了
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
break;
}
// 如果当前构造方法的参数个数小于可用的构造函数中,最小参数个数的话的情况
// 那表示当前构造方法肯定不满足,因为最小可用的构造方法个数都比你多,说明它不可用
// 继续找下一个
if (parameterCount < minNrOfArgs) {
continue;
}
// 创建一个参数的持有者,保存和各个阶段参数的集合,解析好的结合,未解析的集合
ArgumentsHolder argsHolder;
// 获取构造参数的所有类型
Class<?>[] paramTypes = candidate.getParameterTypes();
// 如果参数已经被解析过了
if (resolvedValues != null) {
// 获取参数的名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
// 如果没有参数名称
if (paramNames == null) {
// 使用参数的本定变量表找
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
// 将解析好的参数封装成ArgumentsHolder对象,下面有方法解释
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
// 如果参数没有被解析
// 表示给了构造参数
else {
// 给定的构造参数和当前构造函数的参数不一样,表示不可用
if (parameterCount != explicitArgs.length) {
continue;
}
// 将参数封装成ArgumentsHolder对象
argsHolder = new ArgumentsHolder(explicitArgs){
// 解析之前原始参数,没有被解析过的值
this.rawArguments = args;
// 实际需要用的参数,只保存解析之后的值
this.arguments = args;
// 预处理的参数,可能解析完成,可能没有解析完成
this.preparedArguments = args;
}
}
// 比较权重,就是那个构造方法的参数集最符合要求
int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 如果它表示最接近的匹配,则选择此构造函数。
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);
}
// 如果有多个可用的构造方法,并且权重一样,再看一下BD中是否设置要严格的解析构造函数,如果设置了严格,抛出异常
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,ambiguousConstructors);
}
// 如果没有指定参数,并且参数已经被解析过了,有可用的参数集
if (explicitArgs == null && argsHolderToUse != null) {
// 缓存当前Bean的构造方法,以及参数信息
argsHolderToUse.storeCache(mbd, constructorToUse){
synchronized (mbd.constructorArgumentLock) {
// 缓存构造方法,或者@Bean方法
mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
// 标记为构造方法参数已经解析完成
mbd.constructorArgumentsResolved = true;
// 如果当前参数持有着被标记了需要被解析
if (this.resolveNecessary) {
// 那么就只能缓存提前准备好的参数,因为后面还要解析
mbd.preparedConstructorArguments = this.preparedArguments;
}
else {
// 否则保存已经解析完成的的参数
mbd.resolvedConstructorArguments = this.arguments;
}
}
}
}
}
// 如果BD中已经缓存了resolvedConstructorOrFactoryMethod构造方法或者@Bean方法,就可以直接实例化
// 或者没有缓存,然后进行一些列的参数解析,找符合条件的构造方法,最终实例化对象
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
/**
* 实例化@Bean方法逻辑,其实@Bean方法的参数就是当做构造注入的形式来处理的,原理是一样的
* 如果下面有说到构造参数,实际上就是@Bean方法参数
* @param explicitArgs @Bean方法的参数
*/
public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
// 创建BeanWrapperImpl
BeanWrapperImpl bw = new BeanWrapperImpl();
// 并初始化类型转换器
this.beanFactory.initBeanWrapper(bw);
// @Bean方法所在的对象
Object factoryBean;
// factoryBean的Class
Class<?> factoryClass;
// @Bean方法是不是静态的
boolean isStatic;
// 获取配置当前@Bean的对象的beanName
String factoryBeanName = mbd.getFactoryBeanName();
// 如果存在
if (factoryBeanName != null) {
// 如果@Bean方法所在的对象的BeanName和当前@Bean返回的Bean的beanName一样,就报错
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
// 获取配置该@Bean的对象,@Bean方法需要用到对象
factoryBean = this.beanFactory.getBean(factoryBeanName);
// 如果该Bean是单例,并且容器中已经存在该beanName对应的Bean,也报错
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
// 获取方法所属对象的类型
factoryClass = factoryBean.getClass();
// 标记非静态方法
isStatic = false;
}
else {
// 如果factoryBeanName为空,表是该方法是静态的
// 如果Bd没有设置Class,抛出异常,因为最终反射还是需要用到Class
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();
// 标记为静态方法
isStatic = true;
}
// 需要使用的@bean方法对象
Method factoryMethodToUse = null;
// @TODO
// 方法需要使用的参数持有者对像
ArgumentsHolder argsHolderToUse = null;
// 执行@Bean方法需要的参数
Object[] argsToUse = null;
// 如果给定了@Bean方法的参数
if (explicitArgs != null) {
// 使用给定的方法参数
argsToUse = explicitArgs;
}
else {
// 需要解析的参数
Object[] argsToResolve = null;
// 这里目的就是获取已经处理过一次Bean对象的缓存信息
synchronized (mbd.constructorArgumentLock) {
// 获取解析过的@Bean方法
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
// 如果之前就缓存解析好了,并且标记做了标记,已经被处理好
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// 缓存时候存入的
// if (ArgumentsHolder.resolveNecessary) {
// mbd.preparedConstructorArguments = this.preparedArguments;
// }
// else {
// mbd.resolvedConstructorArguments = this.arguments;
// }
// 找到已经处理好的缓存的方法参数,要不在resolvedConstructorArguments,要不在preparedConstructorArguments中
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果argsToResolve没有,表示方法参数从来没有处理过,没有被缓存
if (argsToResolve != null) {
// 提前解析方法需要的参数,详见下面resolvePreparedArguments方法解析
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
}
}
// 如果当前Bean的方法没有被缓存,或者该方法参数没有被解析
if (factoryMethodToUse == null || argsToUse == null) {
// 获取对@Bean所属对象的自己的类,因为可能会被代理
factoryClass = ClassUtils.getUserClass(factoryClass);
// 可用的@bean方法
List<Method> candidates = null;
// 该@Bean是否是唯
// 因为可能存在@Bean方法重载,参数不同
// 在isOverriddenByExistingDefinition会处理这种情况,如果有存在在的@Bean方法重载它就不唯一
// 表示该方法虽然beanName一样,但是实际上对应的方法不一样
if (mbd.isFactoryMethodUnique) {
// 使用解析好的方法对象
if (factoryMethodToUse == null) {
factoryMethodToUse = mbd.getResolvedFactoryMethod();
}
// 保存成候选的方法candidates
if (factoryMethodToUse != null) {
candidates = Collections.singletonList(factoryMethodToUse);
}
}
// 如果没有找到候选的方法
if (candidates == null) {
candidates = new ArrayList<>();
// 获取@bean方法对象中获取方法
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
// 遍历所有的方法
for (Method candidate : rawCandidates) {
// 找符合条件的的方法,isStatic上面就已经处理过了,即使是@Bean对应修饰符
// 如果遍历的所有方法中,和当前方法有着一样的修饰符,并且也是@Bean方法,就表示可以用
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidates.add(candidate);
}
}
}
// 方法只有一个,并且没有给定方法参数,BD中也没有设置方法参数
// 就不需要解析方法参数
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;
}
// 实例化,并保存到BeanWrapper中,实例化过程详见上面的instantiate方法,实例化@Bean方法的实现
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// 如果存在@Bean方法的重载,方法名一样,方法参数不一样
if (candidates.size() > 1)
// 对两个@Bean进行排序
// 优先比访问修饰符public,再比方法参数,方法参数多,则优先
candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
}
// 解析的方法参数值
ConstructorArgumentValues resolvedValues = null;
// 获取当前Bean的注入模式是不是构造注入
// @Bean方法都是构造注入
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
// 最合适的@Bean方法的权重算法
int minTypeDiffWeight = Integer.MAX_VALUE;
// 保存多个可用的,但是无法选出独有的方法集合
Set<Method> ambiguousFactoryMethods = null;
// 记录可用的方法参数的最小个数
int minNrOfArgs;
// 如果给定了方法参数
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 没有给定,看对于BD是否添加了方法参数
if (mbd.hasConstructorArgumentValues()) {
// 获取存在BD中自己设置的参数值
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析方法参数值,详见下面resolveConstructorArguments,并返回可用方法函数的最小参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
else {
// 如果没有方法参数
minNrOfArgs = 0;
}
}
// 异常的集合
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历所有可用的@Bean方法
for (Method candidate : candidates) {
// 获取方法的个数
int parameterCount = candidate.getParameterCount();
// 只有当前方法参数大于最小可用的参数的时候,才需要对参数进行解析
// 因为当前方法参数都小于必要的参数个数,那该方法肯定是不能用的
if (parameterCount >= minNrOfArgs) {
ArgumentsHolder argsHolder;
// 获取所有的参数类型
Class<?>[] paramTypes = candidate.getParameterTypes();
// 如果有给定方法参数
if (explicitArgs != null) {
// 但是当前方法的参数个不相同,表示这个方法不可用
if (paramTypes.length != explicitArgs.length) {
continue;
}
// 将参数封装成ArgumentsHolder对象
argsHolder = new ArgumentsHolder(explicitArgs){
// 解析之前原始参数,没有被解析过的值
this.rawArguments = args;
// 实际需要用的参数,只保存解析之后的值
this.arguments = args;
// 预处理的参数,可能解析完成,可能没有解析完成
this.preparedArguments = args;
}
}
// 没有给定方法参数
else {
String[] paramNames = null;
// 时候参数名解析器解析方法参数名
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
// 将解析好的参数封装成ArgumentsHolder对象,下面有方法解释
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
}
// 比较权重,就是那个方法的参数集最符合要求
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 (factoryMethodToUse == null || argsToUse == 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: " );
}
// 如果有可用的方法,但是方法返回void,直接抛出异常
else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, needs to have a non-void return type!");
}
// 如果存在多个同时可用的@Bean方法,也抛出异常,因为不知道用哪一个
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription());
}
// 如果没有给定方法参数,但是自己解析过参数
if (explicitArgs == null && argsHolderToUse != null) {
// 将当前使用的方法缓存
mbd.factoryMethodToIntrospect = factoryMethodToUse;
// 缓存参数
argsHolderToUse.storeCache(mbd, factoryMethodToUse){
synchronized (mbd.constructorArgumentLock) {
// 缓存@Bean方法
mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
// 标记为方法参数已经解析完成
mbd.constructorArgumentsResolved = true;
// 如果当前参数持有着被标记了需要被解析
if (this.resolveNecessary) {
// 那么就只能缓存提前准备好的参数,因为后面还要解析
mbd.preparedConstructorArguments = this.preparedArguments;
}
else {
// 否则保存已经解析完成的的参数
mbd.resolvedConstructorArguments = this.arguments;
}
}
}
}
}
// 如果BD中已经缓存了resolvedConstructorOrFactoryMethod构造方法或者@Bean方法,就可以直接实例化
// 或者没有缓存,然后进行一些列的参数解析,找符合条件的方法,最终执行该方法
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
/**
* 解析构造方法参数,这里就是在BD中设置的构造函数参数进行对应的值转换如果有必要,然后在使用转换后的参数创建对象
*/
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
// 获取自定义类型转换器
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
// 如果不存在自定的,使用BeanWrapper包装器
TypeConverter converter = (customConverter != null ? customConverter : bw);
// 创建BDValue解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
// 获取构造方法参数的个数,包括index设置的以及普通泛型的设置的
int minNrOfArgs = cargs.getArgumentCount() {
return (this.indexedArgumentValues.size() + this.genericArgumentValues.size());
}
// 遍历构造方法的所有键值对,先遍历按照Index设置的构造方法
// 可以利用index-value来表示第几个构造参数为什么
for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
int index = entry.getKey();
if (index < 0) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid constructor argument index: " + index);
}
// 动态更新符合条件构造方法的最小参数个数
// 因为当前索引比给定的构造参数个数要大,就是单纯的记一下个数,也不会进行索引校验
// 外面会根据这个数量来对不满足(小于)构造参数的的数量进行过滤
if (index > minNrOfArgs) {
minNrOfArgs = index + 1;
}
// 获取构造函数值
ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
// 如果值已经类型转换成功了
if (valueHolder.isConverted()) {
// 将类型转换后的值重新放回去
resolvedValues.addIndexedArgumentValue(index, valueHolder);
} else {
// 如果没解析好,使用值解析器进行解析
// 就是可能给定的值是beanName,是占位符,或者可能是BD
// 会处理以下类型
// RuntimeBeanReference -> <bean ref=''/>
// RuntimeBeanNameReference
// BeanDefinitionHolder
// BeanDefinition
// DependencyDescriptor(依赖注入引用的bean对应的操作类)
// ManagedArray,ManagedList,ManagedSet,ManagedMap,ManagedProperties,TypedStringValue
// 将最终的值转换为Bean对象,实际上这些多数是在Xml中配置的属性对应成解析到的类
/**
* 案例:
* <pre>
* RootBeanDefinition bd = new RootBeanDefinition();
* ConstructorArgumentValues values = bd.getConstructorArgumentValues();
* // 如果我这里要的b实际上是一个Bean的BeanName呢?我们这样设置的"b"只会当成一个值
* // 如果要当成一个Bean呢,就和xml中配置的ref一样,它最终会生成一个对象
* // 所以,可以修改成这样,RuntimeBeanReference表示对BeanName为b的引用,RuntimeBeanNameReference表示对beanName为c的动态引用
* // RuntimeBeanReference和RuntimeBeanNameReference区别是,前者是立刻解析好beanName对应的bean进行引用
* // 而后者是存的一致是beanName,要用到的时候,在通过BeanName去引用容器中的Bean,其实都差不多
* // bd.getConstructorArgumentValues().addIndexedArgumentValue(1, new RuntimeBeanReference("b"));
* // bd.getConstructorArgumentValues().addIndexedArgumentValue(2, new RuntimeBeanNameReference("c"));
* values.addIndexedArgumentValue(1, "b");
* bd.setBeanClass(F.class);
* registry.registerBeanDefinition("f", bd);
* </pre>
*/
Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 封装成ValueHolder对象
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 {
// 如果没解析好,使用值解析器进行解析
// 就是可能给定的值是beanName,是占位符,可能是Bean的依赖关系,或者可能是BD
// 将最终的值转换为Bean对象,上面有案例
Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 封装成ValueHolder对象
ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
// 将解析后类型转换后的值重新放回去
resolvedValueHolder.setSource(valueHolder);
resolvedValues.addGenericArgumentValue(resolvedValueHolder);
}
}
// 返回
return minNrOfArgs;
}
/**
* 创建构造函数/或者@Bean方法的参数集合,如果是@Bean方法,构造参数指的就是方法参数
* 因为方法参数和构造方法参数一样,都是需要立即注入的
*/
private ArgumentsHolder createArgumentArray(String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues, BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Executable executable, boolean autowiring, boolean fallback) {
// 自定义的类型转换器
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
// 确定需要使用的类型转换器
TypeConverter converter = (customConverter != null ? customConverter : bw);
// 创建一个参数的持有者
// 下面所谓的解析,就是类型转换,根据给定的参数值转换成实际的需要的值
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length) {
// 解析之前原始参数,没有被解析过的值
public final Object[] rawArguments;
// 实际需要用的参数,只保存解析之后的值
public final Object[] arguments;
// 预处理的参数,可能解析完成,可能没有解析完成
public final Object[] preparedArguments;
// 标记当前参数集合的值是否需要解析
public boolean resolveNecessary = false;
}
// 需要使用到的构造参数集合
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
// 需要注入的beanName
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 遍历所有的参数
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
// 获取参数类型
Class<?> paramType = paramTypes[paramIndex];
// 如果没有,使用""
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// 尝试查找匹配的构造函数参数值,无论是索引的还是泛型的
ConstructorArgumentValues.ValueHolder valueHolder = null;
// 如果传递了解析好的构造函数集合
if (resolvedValues != null) {
// 遍历所有的构造函数值,找到一个符合条件的值对象
// 根据参数索引,参数类型和参数名称获取对应的构造参数值
// usedValueHolders是一个过滤作用,已经保存过的就直接跳过
// 先从indexedArgumentValues找,再从genericArgumentValues中
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// 如果没有找到合适类型的参数值,并且不是构造注入的情况下,或者参数个数匹配
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
// 不限制索引和参数类型再找一次,从genericArgumentValues找,因为可能存在泛型
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
// 如果找到了
if (valueHolder != null) {
// 保存找到过的参数值
usedValueHolders.add(valueHolder);
// 保存原始值
Object originalValue = valueHolder.getValue();
// 转换后的值
Object convertedValue;
// 如果值已经进行了类型转换了
if (valueHolder.isConverted()) {
// 获取转换后的值
convertedValue = valueHolder.getConvertedValue();
// 这种情况,convertedValue已经解析完成了,保存到preparedArguments变量中
// preparedArguments变量保存的可能是解析完成的值,或者未解析完成的值
// 确保preparedArguments参数个数与所有的参数个数一致,所以,解析好的值也保存到这里
// 下面还有其他情况,就是值未被解析完成,只能保存到这preparedArguments
args.preparedArguments[paramIndex] = convertedValue;
} else {
// 如果没有转换过
// 获取到构造方法
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// 使用类型转换器将原始值转换
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
// 获取解析之前值的持有者
Object sourceHolder = valueHolder.getSource();
// 如果类型是构造参数的值的话
if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
// 获取到解析之前对应的值
// 在这之前,解析构造函数参数的时候,会做一件事,使用BeanDefinitionValueResolver解析ref,list这行属性,然后得到解析之后的值
// 但是这个值还没有进行类型转换,要看resolveConstructorArguments方法就明白
Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
// 标记这个参数args:ArgumentsHolder需要进行解析
args.resolveNecessary = true;
// sourceValue是未解析的值,所以它只能将值保存到preparedArguments中,preparedArguments是保存未完成最终解析(最终可用参数)的值
args.preparedArguments[paramIndex] = sourceValue;
}
}
// 保存解析后的值,arguments这个变量是保存所有解析之后,可用的值
args.arguments[paramIndex] = convertedValue;
// 这个变量是保存了未被解析的原始值
args.rawArguments[paramIndex] = originalValue;
}
// 如果没有找到符合条件的构造参数
else {
// 获取到构造方法
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// 如果当前注入方式不是构造注入的话,就抛出异常
// 说白了就是没有找到构造方法指定索引下对应的的值,然后又不是构造注入,所以也不会去容器中找Bean
// 所以这个构造方法就没办法创建对象了
if (!autowiring) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam));
}
try {
// 解析需要注入的参数,见下面resolveAutowiredArgument方法解析
Object autowiredArgument = resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter, fallback);
// 保存原始的值
args.rawArguments[paramIndex] = autowiredArgument;
// 保存需要注入的值
args.arguments[paramIndex] = autowiredArgument;
// 保存提前处理的值,一个空对象
args.preparedArguments[paramIndex] = autowiredArgumentMarker;
// 标记该参数对象需要被解析
args.resolveNecessary = true;
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
// 遍历需要注入的beanName
for (String autowiredBeanName : autowiredBeanNames) {
// 注册Beand的依赖关系
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
}
// 返回解析好的参数持有者
return args;
}
/**
* 将给定的构造函数参数进行提前解析
*/
private Object[] resolvePreparedArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, Executable executable, Object[] argsToResolve, boolean fallback) {
// 获取自定义类型转换器
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
// 创建BDValue解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
// 所有构造函数的所有参数类型
Class<?>[] paramTypes = executable.getParameterTypes();
// 解析之后的参数值
Object[] resolvedArgs = new Object[argsToResolve.length];
// 遍历所有的参数
for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
// 获取需要被解析的值
Object argValue = argsToResolve[argIndex];
// 创建方法参数对象
MethodParameter methodParam = MethodParameter.forExecutable(executable, argIndex);
// private static final Object autowiredArgumentMarker = new Object();
// 如果值为一个标记值,表示这需要对这个值进行注入解析
if (argValue == autowiredArgumentMarker) {
// 解析需要注入的参数,见下面resolveAutowiredArgument方法解析
argValue = resolveAutowiredArgument(methodParam, beanName, null, converter, fallback);
}
// 如果参数为Bean元素,ValueHolder,AbstractBeanDefinition等等都是这种类型
if (argValue instanceof BeanMetadataElement) {
// 使用值解析器进行解析,上面有解析
argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
}
// 如果为String类型,解析一下SPEL表达式
if (argValue instanceof String) {
argValue = this.beanFactory.evaluateBeanDefinitionString((String) argValue, mbd);
}
// 获取参数类型
Class<?> paramType = paramTypes[argIndex];
// 对解析后的值进行类型转换
resolvedArgs[argIndex] = converter.convertIfNecessary(argValue, paramType, methodParam);
}
// 返回主让后的值
return resolvedArgs;
}
/**
* 获取用户可以的构造方法,用于获取用户实际类的构造方法,因为类可能被代理
*/
protected Constructor<?> getUserDeclaredConstructor(Constructor<?> constructor) {
// 获取类
Class<?> declaringClass = constructor.getDeclaringClass();
// 获取实际类型,因为可能经过代理了
Class<?> userClass = ClassUtils.getUserClass(declaringClass);
// 如果类被代理了
if (userClass != declaringClass) {
// 获取实际类指定参数的构造方法
return userClass.getDeclaredConstructor(constructor.getParameterTypes());
}
return constructor;
}
/**
* 解析注入的参数
*/
protected Object resolveAutowiredArgument(MethodParameter param, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) {
// 获取参数类型
Class<?> paramType = param.getParameterType();
// 如果参数是InjectionPoint注入点类型
// 表示当前该类正在被注入的过程中
if (InjectionPoint.class.isAssignableFrom(paramType)) {
// 获取当前正在注入的类
InjectionPoint injectionPoint = currentInjectionPoint.get();
if (injectionPoint == null) {
throw new IllegalStateException("No current InjectionPoint available for " + param);
}
// 直接返回正在注入的这个类就行了
return injectionPoint;
}
// 使用工厂解析这个需要注入的Bean,详见@Autowired,@Resource,@Value注入的核心逻辑原理
// DependencyDescriptor就是一个注入点InjectionPoint类型,在注入之前,解析该Bean的情况下
// 会将执行InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
// 将当前注入点保存起来,表示当前bean正在被解析
return this.beanFactory.resolveDependency(new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
}
}