我有以下界面:
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 仍然会抱怨,并且无法识别它
您可以使用 @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";
}
}
由于您使用的是 java 配置,因此您应该使用
@Primary
注释来标记配置方法,而不是类:
@Configuration
public class MailConfig {
@Bean
public SmtpkMailSender getSmtpkMailSender(){
return new SmtpkMailSender();
}
@Bean
@Primary
public MockMailSender getMockMailSender(){
return new MockMailSender();
}
}
此错误的另一个解决方案是从“
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
注释更新源代码来解决错误。@Qualifier
然后用装饰自动连线字段
@Bean(name="mockMailSender")
public MockMailSender getMockMailSender() { }