我有兩個(將來會更多)實作ImportantService–VeryImportantService和LessImportantService:
public interface ImportantService<T extends ImportantRequest> {}
@Service
public class VeryImportantService implements ImportantService<VeryImportantRequest> {}
@Service
public class LessImportantService implements ImportantService<LessImportantRequest> {}
然后我有一個控制器,我想在其中注入以下所有實作ImportantService:
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/important")
public class ImportantController<T extends ImportantRequest> {
private final ImportantService<T> importantService;
@PostMapping
public ResponseEntity<ImportantResponse> create(@RequestBody @Valid T request) {
// very important code here
}
}
顯然,這樣的注入之王失敗了:
UnsatisfiedDependencyException: Error creating bean with name 'importantController' defined in file ...
...
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
我想要的是:
注入所有的實作ImportantService,然后,基于T自動選擇所需的bean。我知道我可以將方法添加到ImportantService,它回傳實作使用的型別,然后注入ImportantService,List<ImportantService> importantServices然后像這樣過濾:
importantServices.stream()
.filter(importantService -> importantService.getType().equals(request.getClass()))
.findFirst()
.ifPresent(importantService -> importantService.doImportantJob(request));
但!我有數百個服務要像這樣重構,我真的不想為控制器撰寫額外的邏輯。
我知道@Conditional注釋和Condition界面,但是 AFAIK 沒有辦法讓他們做我想做的事。
uj5u.com熱心網友回復:
為什么不實作代理模式?
例子:
@Service
@Primary
@RequiredArgsConstructor
public class ImportantServiceProxy implements ImportantService<T extends ImportantRequest> {
private final List<ImportantService> importantServices;
private ImportantService getImportantService(ImportantRequest request){
return this.importantServices.stream()
.filter(importantService -> importantService.getType().equals(request.getClass()))
.findFirst()
.get();
}
public void doImportantJob(ImportantRequest request){
this.getImportantService(request).doImportantJob(request);
}
}
然后在您的控制器中,您可以在不檢查型別的情況下呼叫該函式。
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/important")
public class ImportantController<T extends ImportantRequest> {
private final ImportantService<T> importantService;
@PostMapping
public ResponseEntity<ImportantResponse> create(@RequestBody @Valid T request) {
importantService.doImportantJob(request);
}
}
uj5u.com熱心網友回復:
你想要的是一個重要服務型別的bean串列,所以你必須宣告一個像這樣的變數。
final List<ImportantService> importantServices;
demoController(List<ImportantService> importantServices) {
this.importantServices = importantServices;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/446008.html
