Spring中Autowire.BY_NAME注入出现参数歧义错误原因咨询
为什么给@Bean设置autowire=Autowire.BY_NAME会引发参数歧义错误?
问题场景
有两个类A和B,B通过构造器依赖A。在配置类中给Bean-B的@Bean注解设置autowire = Autowire.BY_NAME后,初始化Spring上下文时抛出Ambiguous argument values for parameter of type错误;移除该配置后程序正常运行。
相关代码
类A
package com.pm.spring; public class A { public A() { System.out.println("Default Constructor in A"); } }
类B
package com.pm.spring; public class B { A a; public B(A a) { super(); System.out.println("Parameterized Constructor in B"); this.a = a; } }
报错时的配置类
package com.pm.spring; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean(name = "Bean-A") public A createA() { A a = new A(); return a; } @Bean(name = "Bean-B", autowire = Autowire.BY_NAME) public B createB(A a) { B b = new B(a); return b; } }
错误信息
Default Constructor in A Jan 08, 2025 12:52:58 PM org.springframework.context.support.AbstractApplicationContext refresh WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'Bean-B' defined in com.pm.spring.AppConfig: Unsatisfied dependency expressed through method 'createB' parameter 0: Ambiguous argument values for parameter of type [com.pm.spring.A] - did you specify the correct bean references as arguments? Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'Bean-B' defined in com.pm.spring.AppConfig: Unsatisfied dependency expressed through method 'createB' parameter 0: Ambiguous argument values for parameter of type [com.pm.spring.A] - did you specify the correct bean references as arguments? at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:785) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:539) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:882) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:89) at com.pm.spring.Demo.main(Demo.java:10)
正常运行的配置类
package com.pm.spring; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean(name = "Bean-A") public A createA() { A a = new A(); return a; } @Bean(name = "Bean-B") public B createB(A a) { B b = new B(a); return b; } }
错误原因解析
正常运行的逻辑
当@Bean方法声明参数(比如createB(A a))时,Spring默认会按类型自动装配参数:容器里只有一个A类型的Bean(名为Bean-A),所以Spring直接将其注入到createB的参数中,顺利创建B实例,程序正常运行。
加autowire=Autowire.BY_NAME后的冲突
@Bean的autowire属性是用来指定Bean实例创建后的属性自动装配模式(对应XML配置的<bean autowire="byName"/>),但它和@Bean方法的参数注入逻辑会产生冲突:
- 设置
autowire = Autowire.BY_NAME后,Spring会在通过createB方法创建B实例后,尝试对B的字段A a按名称自动装配——即寻找名为a的Bean注入。 - 但同时,
createB方法本身已经通过参数接收了A实例,并传给B的构造器完成了依赖注入。 - 此时Spring的依赖解析逻辑出现混乱:它认为B对A的依赖既可以通过方法参数的类型注入满足,又可以通过BY_NAME的属性装配满足,两种注入路径导致参数解析时出现歧义,因此抛出
Ambiguous argument values错误。
另外需要注意:@Bean的autowire属性从Spring 5.1开始已被标记为过时(Deprecated),官方推荐直接通过方法参数注入(即正常运行的写法),或使用@Autowired注解处理依赖,避免此类混淆。
内容的提问来源于stack exchange,提问作者Pravesh
相关产品推荐
相关产品推荐

