SpringBoot是否根据变量名进行bean选择?

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

我最近决定尝试一下 Spring 的 Bean 注入。

当有两个相同类型的 Bean 定义但应用程序开始运行时,我试图引发我的应用程序失败。 我想出了这个模式:

这就是我的简单界面

public interface Demo {

  String getMessage();
}

实现该接口的两个类

@Service
public class DemoService implements Demo{

  private final DataRepo repo;

  DemoService(DataRepo repo) {
    this.repo = repo;
  }

  @Override
  public String getMessage() {
    return "Demo message from Demo Service";
  }
}
@Service
public class DemoSecondService implements Demo{

  private final DataRepo repo;

  DemoSecondService(DataRepo repo) {
    this.repo = repo;
  }

  @Override
  public String getMessage() {
    return "Demo message from DemoSecondService";
  }
}

那是我的控制器:

@RestController
@RequestMapping("/demo")
public class DemoController {

  private final Demo demoSecondService; //(1)

  public DemoController(Demo demoSecondService) {
    this.demoSecondService = demoSecondService;
  }

  @GetMapping
  ResponseEntity<String> hello() {
    return new ResponseEntity<>("Hello", HttpStatus.OK);
  }

  @GetMapping("/more")
  ResponseEntity<String> moreHello() {

    String message = demoSecondService.getMessage();
    return new ResponseEntity<>(message, HttpStatus.OK);
  }

所以,我注意到,尽管有两个“Demo”类型的 Bean,即使我不使用 @Qualifier 注释,Spring 在 DemoController 中注入 Bean 也没有任何问题。如果控制器中只有 Demo 变量名称为“demoSecondService”,Spring 会注入 DemoSecondService Bean,如果变量名称为 demoService,Spring 会自动注入 DemoService Bean。即使变量的名称如 demoSecondServiceXXXXX,这也有效。当变量名称更改为与类名称完全不同的名称时,例如“newName”,那么正如预期的那样,Spring 告诉它无法选择我想在控制器中注入哪个 bean:

Parameter 0 of constructor in com.example.demo.domain.controller.DemoController required a single bean, but 2 were found:
    - demoSecondService: defined in file 
    - demoService: defined in file 

那么为什么在变量名与类名匹配的情况下,Spring可以注入特定的Bean呢? SpringBoot 是否根据变量名称进行 bean 选择,以便我们可以在不使用 @Qualifier 的情况下使用它?

java spring-boot inversion-of-control constructor-injection
1个回答
0
投票

我在每个服务中实现了一个构造函数来跟踪行为,我发现它注入了或者至少实例化了两者:

@服务 公共类 DemoService 实现 Demo{

private DataRepo repo;

public DemoService() {
    System.out.println("First...");
}

......

@服务 公共类 DemoSecondService 实现 Demo{

private DataRepo repo;

public DemoSecondService() {
    System.out.println("Second...");
}

......

在此输入图片描述

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