[英]Constructor Dependency Injection in Spring with abstract classes
我想在我的應用程序中使用構造函數依賴注入。
我已經創建了這個 controller:
public abstract class BonanzaCloudController {
protected final UserService userService;
protected BonanzaCloudController(UserService userService) {
this.userService = userService;
}
...
}
和這個
@Controller
public class AppErrorController extends BonanzaCloudController implements ErrorController {
private final ErrorAttributes errorAttributes;
private final EmailService emailService;
public AppErrorController(ErrorAttributes errorAttributes, EmailService emailService) {
this.errorAttributes = errorAttributes;
this.emailService = emailService;
}
...
}
但我有這個編譯錯誤:
There is no default constructor available in BonanzaCloudController
AppErrorController
是 BonanzaCloudController 的子類,因此BonanzaCloudController
的構造函數必須調用AppErrorController
的構造BonanzaCloudController
(由 java 定義的規則)。
因此AppErrorController
的構造函數必須是
public AppErrorController(UserService userService, ErrorAttributes errorAttributes, EmailService emailService) {
super(userService);
this.errorAttributes = errorAttributes;
this.emailService = emailService;
}
雖然userService
不必是第一個參數,但只有super()
調用必須是第一個參數。
這不是 Spring DI 問題,而是 class 層次結構的問題。 要構造AppErrorController
, JVM 將需要構造其超類的基本實例,但您尚未為其提供執行此操作的方法。 您將需要創建一個默認構造函數或顯式調用super(...)
並傳遞UserService
的實例。
這與 Spring 無關。 它是 Java。
你有基礎 class BonanzaCloudController
。 你用 1 個參數聲明構造函數,這意味着沒有參數的構造函數將不再存在:
protected BonanzaCloudController(UserService userService) { }
現在你有了一個孩子 class:
public class AppErrorController extends BonanzaCloudController {
public AppErrorController(ErrorAttributes errorAttributes, EmailService emailService) {
// this is how your constructor looks, super is implicit there
// means that you don't need to add it, it will be there anyway.
super();
this.errorAttributes = errorAttributes;
this.emailService = emailService;
}
}
上面的代碼中有我的小注釋。 當創建子 class 的實例時 - 首先調用基本 class 構造函數來實例化 object 的“基本”部分。 在我們的例子中,它是super();
在這里它指的是基礎 class 中的no-arg constructor
函數(因為它只是super()
,沒有參數),而您的基礎 class 中根本沒有它。
所以要解決這個問題,你基本上有兩個選擇。 首先,您可以使用基礎 class 中的參數調用構造函數:
public AppErrorController(ErrorAttributes errorAttributes, EmailService emailService) {
// the first call should be an explicit call of super(...)
// as a param you need instance of UserService
super(userService);
this.errorAttributes = errorAttributes;
this.emailService = emailService;
}
或者您可以將無參數構造函數添加到您的基礎 class ,然后您根本不需要調用 super 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.