我遇到了这个特定问题,我无法使用 @Qualifier
因为我需要父类中的 bean。我的想法是删除 baseComponent
属性并在 BaseController
中创建一个抽象方法,例如 getComponent()
并返回 BaseComponent 所需的 bean
...但也许有一种更简洁的方法可以通过配置来做到这一点。
@RestController
public abstract class BaseController {
@Autowired
private BaseComponent baseComponent;
@GetMapping("/something")
public void doSomething() {
baseComponent.printSomething();
}
}
@RestController
@RequestMapping(value = "/foo")
public class FooController extends BaseController {
}
@RestController
@RequestMapping(value = "/bar")
public class BarController extends BaseController {
}
public interface BaseComponent {
void printSomething();
}
@Component
public class FooComponent implements BaseComponent {
@Override
public void printSomething() {
System.out.println("foo!");
}
}
@Component
public class BarComponent implements BaseComponent{
@Override
public void printSomething() {
System.out.println("bar!");
}
}
最佳答案
这是我不喜欢直接 Autowiring 到私有(private)字段的原因之一。我将通过 BaseController 的构造函数注入(inject) BaseComponent 来完成此操作:
public abstract class BaseController {
private final BaseComponent baseComponent;
protected BaseController(BaseComponent baseComponent){
this.baseComponent = baseComponent;
}
@GetMapping("/something")
public ResponseEntity<String> getSomething(){
return new ResponseEntity<String>(baseComponent.getSomething(), HttpStatus.OK);
}
}
@RestController
@RequestMapping("/foo")
public class FooController extends BaseController{
@Autowired
public FooController(@Qualifier("fooComponent") BaseComponent baseComponent) {
super(baseComponent);
}
}
@RestController
@RequestMapping("/bar")
public class BarController extends BaseController{
@Autowired
public BarController(@Qualifier("barComponent") BaseComponent baseComponent){
super(baseComponent);
}
}
@Component
public class BarComponent implements BaseComponent {
@Override
public String getSomething() {
return "bar";
}
}
@Component
public class FooComponent implements BaseComponent {
@Override
public String getSomething() {
return "foo";
}
}
对/something/bar的请求将返回bar,对something/foo的请求将返回foo。
请注意,抽象BaseComponent
实际上并未声明为任何类型的Spring组件,也没有自动注入(inject)任何依赖项。相反,子类是组件,依赖项被连接到它们的构造函数中,并通过 super
传递到 BaseComponent
。子类构造函数为 @Qualifier
注释提供了一个位置来指定您想要的 BaseComponent
。
理论上,我不喜欢声明两个除了注释之外相同的类。但在实践中,我发现有时最简单的方法就是声明类来保存 Spring 注释。这比过去的 XML 配置要好。
关于java - 有什么方法可以知道在 Spring 中从父类使用什么 bean 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58526209/