我有一个特定的问题,我不能使用@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!");
}
}
最佳答案
这是我不喜欢直接自动布线到私有字段的原因之一。我可以通过通过BaseController的构造函数注入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组件,也没有自动注入任何依赖项。而是将子类作为组件,并将依赖项连接到其构造函数中,并通过super
传递给BaseComponent
。子类构造函数为@Qualifier
批注提供一个位置,以指定所需的BaseComponent
。从理论上讲,我不喜欢声明两个与注解相同的类。但是,在实践中,我发现有时仅声明类来保存Spring批注是最简单的。这比过去的XML配置要好。