Spring构造器自动注入报错:多个同类型Parrot Bean冲突
Spring构造器注入多Bean匹配错误解决方案
我正在通过《Spring Start Here》学习Spring框架,已在Spring上下文中注册了两个Parrot类的Bean(parrot1和parrot2),尝试通过构造器自动将parrot2注入到Person类中,但持续收到报错:
"Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'beans.Parrot' available: expected single matching bean but found 2: parrot1,parrot2"
原本以为构造器参数名与bean名称匹配就不会有问题,尝试使用@Qualifier注解后仍出现相同错误。相关代码及错误信息如下:
相关代码
配置类(ProjectConfig.java)
package config; import beans.Parrot; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = "beans") public class ProjectConfig { @Bean public Parrot parrot1() { Parrot p = new Parrot(); p.setName("Koko"); return p; } @Bean public Parrot parrot2() { Parrot p = new Parrot(); p.setName("Miki"); return p; } }
Parrot类(Parrot.java)
package beans; public class Parrot { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Parrot : " + name; } }
Person类(Person.java)
package beans; import org.springframework.stereotype.Component; @Component public class Person { private String name = "Ella"; private final Parrot parrot; public Person(Parrot parrot2) { this.parrot = parrot2; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Parrot getParrot() { return parrot; } }
主类(Main.java)
package main; import beans.Person; import config.ProjectConfig; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { var context = new AnnotationConfigApplicationContext(ProjectConfig.class); Person p = context.getBean(Person.class); System.out.println("Person's name: " + p.getName()); System.out.println("Person's parrot: " + p.getParrot()); } }
错误信息
Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'beans.Parrot' available: expected single matching bean but found 2: parrot1,parrot2 Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'person' defined in file [C:\Users\Ian36\IdeaProjects\BENAS\target\classes\beans\Person.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'beans.Parrot' available: expected single matching bean but found 2: parrot1,parrot2 at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:802) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:241) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:960) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:93) at main.Main.main(Main.java:9) Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'beans.Parrot' available: expected single matching bean but found 2: parrot1,parrot2 at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:218) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1420) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:911) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) ... 14 more Process finished with exit code 1
解决方案
方法1:正确使用@Qualifier注解
你之前的@Qualifier可能未正确添加到构造器参数上,需要在参数前标注@Qualifier("parrot2"),并确保导入对应的包。修改后的Person类代码如下:
package beans; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class Person { private String name = "Ella"; private final Parrot parrot; public Person(@Qualifier("parrot2") Parrot parrot2) { this.parrot = parrot2; } // getter、setter和toString方法保持不变 }
方法2:开启编译参数保留构造器参数名
Spring支持通过构造器参数名匹配Bean名称,但前提是编译时保留了参数名信息。如果使用Java 8+,需要在编译配置中添加-parameters参数,让Spring能识别到参数名parrot2。
Maven配置示例(pom.xml):
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>11</source> <!-- 替换为你的Java版本 --> <target>11</target> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin> </plugins> </build>
方法3:标记其中一个Bean为@Primary
如果parrot2是多数场景下默认需要注入的Bean,可以在其@Bean注解上添加@Primary,让Spring优先选择该Bean:
package config; import beans.Parrot; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @Configuration @ComponentScan(basePackages = "beans") public class ProjectConfig { @Bean public Parrot parrot1() { Parrot p = new Parrot(); p.setName("Koko"); return p; } @Primary @Bean public Parrot parrot2() { Parrot p = new Parrot(); p.setName("Miki"); return p; } }
内容的提问来源于stack exchange,提问作者Ian
相关产品推荐
相关产品推荐

