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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46343560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 09:10:12  来源:igfitidea点击:

class required a single bean, but 2 were found:

javaspringspring-mvc

提问by Jeff

I have the below interface:

我有以下界面:

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

With 2 imlementation of it:

有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);
    }

}

and the second one is:

第二个是:

@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);
    }

}

I used the dependency injection into the controller class which is as following:

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

@RestController
public class MailController {

    @Autowired
    private MailSender smtpkMailSender;

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

At the end i have a configuration class which contains my Beans:

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

@Configuration
public class MailConfig {

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

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

}

Unfortunatly, when i run my application it complains with:

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

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

As you see, although i have specified the MockMailSenderas Primary the spring still complains, and cannot identify it

如您所见,尽管我已将其指定MockMailSender为 Primary,但 spring 仍会抱怨,并且无法识别它

采纳答案by Leffchik

Since you're using java config you should mark config method with @Primaryannotation, and not a class:

由于您使用的是 java config,您应该用@Primary注释标记 config 方法,而不是类:

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

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

回答by Yogi

You can use @Qualifier annotation for specify which specific type of your implementation, you want to autowire.

您可以使用 @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";
  }

}

}

回答by iAbhinav

You may simply name your bean using

您可以简单地使用命名您的 bean

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

and then decorate the autowired field with

然后用

@Autowired
@Qualifier("mockMailSender")
private MailSender smtpkMailSender;