我最近决定尝试一下 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 的情况下使用它?
我在每个服务中实现了一个构造函数来跟踪行为,我发现它注入了或者至少实例化了两者:
@服务 公共类 DemoService 实现 Demo{
private DataRepo repo;
public DemoService() {
System.out.println("First...");
}
......
@服务 公共类 DemoSecondService 实现 Demo{
private DataRepo repo;
public DemoSecondService() {
System.out.println("Second...");
}
......