首页 > 解决方案 > 需要单个 bean,但在简单的 spring-boot 应用程序中找到了 2 个

问题描述

我是弹簧靴的新手。所以我正在开发一个简单的应用程序,其中有 2 个服务EnglishLanguageServiceSpanishLanguageService. 最后,我想打印HelloHola当应用程序运行时,我得到了错误

Parameter 0 of constructor in controller.ConstructorInjectedController required a single bean, but 2 were found:
    - profileEnglishLanguageService: defined in file [/Users/user/Downloads/depdency-injection-example/target/classes/services/EnglishLanguageService.class]
    - profileSpanishLanguageService: defined in file [/Users/user/Downloads/depdency-injection-example/target/classes/services/SpanishLanguageService.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

我不确定我哪里出错了。我将在下面粘贴我的代码。

主要应用

@SpringBootApplication
@ComponentScan(basePackages= {"controller" , "services"})
public class DepdencyInjectionExampleApplication {

    public static void main(String[] args) {
        // returns application context
        ApplicationContext ctx = SpringApplication.run(DepdencyInjectionExampleApplication.class, args);

        System.out.println(ctx.getBean(PropertyInjectedController.class).getGreeting());
        System.out.println(ctx.getBean(ConstructorInjectedController.class).getGreetings());

    }

ConstructorInjectedController 类

@Component
public class ConstructorInjectedController {

    private final GreetingService greetingService;

    public ConstructorInjectedController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    public String getGreetings() {
        return greetingService.sayGreetings();
    }

PropertyInjectedControllerClass

@Controller
public class PropertyInjectedController {

    public GreetingService greetingService;

    public String getGreeting() {
        return greetingService.sayGreetings();
    }

}

问候服务接口

public interface GreetingService {

    String sayGreetings();

}

英语服务班

@Service
public class EnglishLanguageService implements GreetingService {

    private GreetingService greetingService;

    public EnglishLanguageService(@Qualifier("english")
                                                 GreetingService greetingService){
        this.greetingService = greetingService;
    }

    @Override
    public String sayGreetings() {
        return greetingService.sayGreetings();
    }

英文ServiceImpl

@Profile("english")
public class EnglishServiceImpl implements GreetingService {
    @Override
    public String sayGreetings() {
        return "Hello";
    }

西班牙语服务

@Service
public class SpanishLanguageService implements GreetingService {

    private GreetingService greetingService;

    public SpanishLanguageService(@Qualifier("spanish")
                                                 GreetingService greetingService){
        this.greetingService = greetingService;
    }
    @Override
    public String sayGreetings() {
        return greetingService.sayGreetings();
    }

西班牙语服务实施

@Profile("spanish")
public class SpanishServiceImpl implements GreetingService {
    @Override
    public String sayGreetings() {
        return "Hola";
    }
}

标签: javaspringspring-boot

解决方案


您使用错误的注释。@Profile用于完全不同于您认为的东西,因此应该将其删除。

您基本上是在对 spring 说“请在 X 类中注入特定的问候服务”。

现在 spring 不知道你想要哪个 bean,因为你有两个不同的 bean 实现了相同的接口。所以我们使用@Qualifier注解来标记一个bean,并在注入期间定位它。

首先,您的实现应该具有 a@Service或 a @Component,以便 spring 在组件扫描期间找到它,并将其实例化为 spring 托管 bean。这与 a 相结合,@Qualifier以便我们对其进行标记,因此我们稍后可以在注入期间选择此标记:

@Component
@Qualifier("english")
public class EnglishServiceImpl implements GreetingService {

    @Override
    public String sayGreetings() {
        return "Hello";
    }
}

在这里,我们注入了问候服务并使用我们的限定符告诉 spring 我们想要注入可用的哪个 bean。

@Service
public class EnglishLanguageService implements GreetingService {

    private GreetingService greetingService;

    public SpanishLanguageService(@Qualifier("english") GreetingService greetingService){
        this.greetingService = greetingService;
    }

    @Override
    public String sayGreetings() {
        return greetingService.sayGreetings();
    }
}

推荐阅读