Ambiguous argument values for parameter of type [???] - did you specify the correct bean references as arguments?
项目启动报错
Ambiguous argument values for parameter of type [???] - did you specify the correct bean references as arguments?
造成原因
Spring在使用构造方法实例化时,尝试使用了能使用的所有构造也无法将对象实例化。
排查方向
- 配置参数是否有误,一般初始化对象的属性都是使用配置文件传入,那么参数是否有配错。(注:这里根据读取配置文件的框架不同会产生影响,比如有些配置服务在读取时会根据服务器情况对读取数据参数做一些替换,换言之这些对象的属性不一定是配置文件中配置的,这一块要注意报错信息里面具体的值)
- Jar包冲突,启动的时候,运行对象的构造函数和你想用的构造函数已经不是一个构造函数。
构造实例化源码
根据报错信息直接定位到报错位置
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
断点打到spring报错源码,看传入参数
浏览整体逻辑发现spring使用构造参数实例化:是循环所有的构造方法达成对象的实例化
for (Constructor<?> candidate : candidates) {
// 开始循环构造方法
Class<?>[] paramTypes = candidate.getParameterTypes();
// 省略一些校验
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
// 省略得到参数名的方法
// 获取构造参数队列
// 在这里解析可以完成构造实例化的对象,如果这里不可以的话会抛出异常
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
catch (UnsatisfiedDependencyException ex) {
// 省略了一些判断
// 在这里收集异常
// 这里就解释了为何异常信息如此之多
if (causes == null) {
causes = new LinkedList<UnsatisfiedDependencyException>();
}
causes.add(ex);
continue;
}
}
}