You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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方法的参数注入逻辑会产生冲突:

  1. 设置autowire = Autowire.BY_NAME后,Spring会在通过createB方法创建B实例后,尝试对B的字段A a按名称自动装配——即寻找名为a的Bean注入。
  2. 但同时,createB方法本身已经通过参数接收了A实例,并传给B的构造器完成了依赖注入。
  3. 此时Spring的依赖解析逻辑出现混乱:它认为B对A的依赖既可以通过方法参数的类型注入满足,又可以通过BY_NAME的属性装配满足,两种注入路径导致参数解析时出现歧义,因此抛出Ambiguous argument values错误。

另外需要注意:@Bean的autowire属性从Spring 5.1开始已被标记为过时(Deprecated),官方推荐直接通过方法参数注入(即正常运行的写法),或使用@Autowired注解处理依赖,避免此类混淆。

内容的提问来源于stack exchange,提问作者Pravesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:42:03