spring_推断构造方法底层执行流程
2022-12-14 13:47:11 1 举报
spring_推断构造方法底层执行流程
作者其他创作
大纲/内容
如果参数个数匹配,则把所有参数值封装为一个ArgumentsHolder对象
Y
对候选者进行排序,按构造方法的参数个数降序排序,参数个数多的在前
如果构造方法和构造方法参数值任意一个为空,则继续进行下面步骤
针对当前BeanDefinition是否缓存了构造方法和构造方法参数值
是否通过getBean()方法指定构造方法参数值
缓存上面所有推断出来的构造方法
N
基于构造方法参数先byType再byName,以及BeanDefinition中所设置的参数一起得到合适当前构造方法的参数值,封装为一个ArgumentsHolder对象
遍历结束
经过上述步骤,判断是否直接确定了构造方法和构造方法参数值
// 对候选构造方法进行排序,public的方法排在最前面,都是public的情况下参数个数越多越靠前AutowireUtils.sortConstructors(candidates);
如果传入了构造方法,则直接把这些构造方法作为候选者
开始遍历候选者
遍历过程中,会选择匹配程度最小的构造方法// 当前遍历的构造方法所需要的入参对象都找到了,根据参数类型和找到的参数对象计算出来一个匹配值,值越小越匹配// Lenient表示宽松模式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);}
// 如果参数个数小于所要求的参数个数,则遍历下一个,这里考虑的是同时存在public和非public的构造方法if (parameterCount < minNrOfArgs) {continue;}
进行推断构造方法
计算构造方法参数个数最少个数minNrOfArgs
判断候选者构造方法是不是只有一个,并且没有指定构造方法参数
// 如果没有指定构造方法,那就获取beanClass中的所有构造方法所谓候选者Constructor<?>[] candidates = chosenCtors;
判断有没有通过getBean()方法指定构造方法参数值
如果没有构造方法,那么则获取当前BeanDefinition对应的beanClass中所有构造方法作为候选者
判断该方法是不是无参构造方法
根据推断出来的构造方法进行实例化
如果构造方法和构造方法参数值都确定了,那么直接使用该构造方法和构造方法参数值进行实例化得到一个对象
缓存该构造方法和构造方法参数值
如果当前候选者的参数个数小于minNrOfArgs,则该候选者不匹配,继续下一个候选者
1、有多个构造方法都可以使用,构造方法上都加上@Autowired(required = false)2、autowiremode为AUTOWIRE_CONSTRUCTOR,<bean id=\"userService\" class=\"com.zhouyu.service.UserService\" autowire=\"constructor\"/>3、BeanDefinition指定了构造方法参数值,通过AbstractBeanDefinition添加构造方法参数......4、getBean指定构造方法参数
计算得到的构造方法参数值和参数的匹配程度
继续遍历下一个后选择
0 条评论
回复 删除
下一页