类需要一个 bean,但找到了 2 个:

问题描述 投票:0回答:4

我有以下界面:

public interface MailSender {
    void sender(String to, String subject,String body);
}

有2个实现:

public class SmtpkMailSender implements MailSender   {

    static Log log=LogFactory.getLog(MailSender.class); 

    public void sender(String to, String subject,String body){
        log.info("SMTP To: "+to);
        log.info("SMTP Subjecy: "+subject);
        log.info("SMTP body: "+body);
    }

}

第二个是:

@Primary
public class MockMailSender implements MailSender   {

    static Log log=LogFactory.getLog(MailSender.class); 

    public void sender(String to, String subject,String body){
        log.info("To: "+to);
        log.info("Subject: "+subject);
        log.info("body: "+body);
    }

}

我使用了控制器类的依赖注入,如下所示:

@RestController
public class MailController {

    @Autowired
    private MailSender smtpkMailSender;

    @RequestMapping("/send")
    public String send(){
        smtpkMailSender.sender("Person", "Important", "Take Care");
        return "mail is sent";
    }
}

最后我有一个包含我的 Bean 的配置类:

@Configuration
public class MailConfig {

    @Bean
    public SmtpkMailSender getSmtpkMailSender(){
        return new SmtpkMailSender();
    }

    @Bean
    public MockMailSender getMockMailSender(){
        return new MockMailSender();
    }

}

不幸的是,当我运行我的应用程序时,它抱怨:

Description:

Field smtpkMailSender in com.example.demo.MailController required a single bean, but 2 were found:
    - getSmtpkMailSender: defined by method 'getSmtpkMailSender' in class path resource [com/example/mail/MailConfig.class]
    - getMockMailSender: defined by method 'getMockMailSender' in class path resource [com/example/mail/MailConfig.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

如您所见,虽然我已将

MockMailSender
指定为 Primary,但 spring 仍然会抱怨,并且无法识别它

java spring spring-mvc
4个回答
21
投票

您可以使用 @Qualifier 注释来指定要自动装配的具体实现类型。

@RestController
public class MailController {
   @Autowired
   @Qualifier("smtpkMailSender")
   private MailSender smtpkMailSender;

   @RequestMapping("/send")
   public String send(){
      smtpkMailSender.sender("Person", "Important", "Take Care");
      return "mail is sent";
  }
}

18
投票

由于您使用的是 java 配置,因此您应该使用

@Primary
注释来标记配置方法,而不是类:

@Configuration
public class MailConfig {
    @Bean
    public SmtpkMailSender getSmtpkMailSender(){
        return new SmtpkMailSender();
    }

    @Bean
    @Primary
    public MockMailSender getMockMailSender(){
        return new MockMailSender();
    }
}

3
投票

此错误的另一个解决方案是从“

application.yml”文件中的
exclude
阶段中删除未使用的Bean(重复的bean),如本线程中所述:如何在 Spring Boot JUnit 测试中排除 AutoConfiguration 类? autoconfiguration

如果在添加新的 Maven/Gradle 依赖项(该依赖项与您正在使用的现有 bean 重复)后出现错误,则这适用。例如,当两个bean都来自外部JAR时,因此无法使用
spring: autoconfigure: exclude: - org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration - org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration

@Primary
注释更新源代码来解决错误。
    


2
投票
命名您的bean

@Qualifier

然后用 
装饰自动连线字段

@Bean(name="mockMailSender") public MockMailSender getMockMailSender() { }

	
© www.soinside.com 2019 - 2024. All rights reserved.