簡體   English   中英

帶有抽象類的 Spring 中的構造函數依賴注入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM