簡體   English   中英

如何正確地將許多服務注入 Spring MVC 控制器?

[英]How do I properly inject many services into Spring MVC controller?

我創建了具有 3 種用戶類型的 Spring MVC 應用程序。 我為每個控制器創建了單獨的控制器。 現在在他們每個人中,我必須注入服務類,所以我這樣做了:

@Controller
@RequestMapping("teacher")
public class TeacherController {

@Autowired
private StudentService studentService;

@Autowired
private GradeService gradeService;

@Autowired
private SubjectService subjectService;

@Autowired
private StudentGroupService studentGroupService;

@Autowired
private NewsService newsService;

@GetMapping("/index")
public String indexPage(Model theModel) {
    List<News> tempNewsList = newsService.getNews();

    theModel.addAttribute("theNewList", tempNewsList);

    return "teacher/index";
}

此代碼使用字段注入。 正如我現在了解到的,這是一個應該避免並用構造函數注入代替的解決方案。 所以我已經自動裝配了一個包含所有這些字段的構造函數,如下所示:

@Autowired
public TeacherController(StudentService studentService, GradeService gradeService, SubjectService subjectService, StudentGroupService studentGroupService, NewsService newsService) {
    this.studentService = studentService;
    this.gradeService = gradeService;
    this.subjectService = subjectService;
    this.studentGroupService = studentGroupService;
    this.newsService = newsService;
}

這是一個很好的解決方案,用如此簡單的代碼創建如此冗長的構造函數嗎? 如果我的代碼中有更多服務怎么辦? 這甚至可以接受還是在這種情況下我應該重構我的代碼,例如將服務委托給其他服務或創建更多控制器?

你自己回答的很好! 春天正是地址在文檔這種擔心在這里在框中名為基於構造函數或setter基於DI?

Spring 團隊通常提倡構造函數注入,因為它可以讓您將應用程序組件實現為不可變對象,並確保所需的依賴項不為空。 此外,構造函數注入的組件總是以完全初始化的狀態返回給客戶端(調用)代碼。 作為旁注,大量的構造函數參數是一種糟糕的代碼味道,這意味着該類可能有太多的責任,應該重構以更好地解決適當的關注點分離問題。

也就是說,您應該理想地進行重構。 使用SOLID原則並思考“我正在創建的班級的一項工作是什么?”。

總之,根據文檔,如果存在許多 DI,您可以評估每個 DI 並嘗試使用基於集合和/或基於構造函數。 文檔說明以下使用哪一個:

基於構造函數還是基於 setter 的 DI?

由於您可以混合使用基於構造函數和基於 setter 的 DI,因此根據經驗,對強制依賴項使用構造函數,對可選依賴項使用 setter 方法或配置方法是一個很好的經驗法則。 請注意,在 setter 方法上使用 @Required 注釋可用於使屬性成為必需的依賴項。

Spring 團隊通常提倡構造函數注入,因為它可以讓您將應用程序組件實現為不可變對象,並確保所需的依賴項不為空。 此外,構造函數注入的組件總是以完全初始化的狀態返回給客戶端(調用)代碼。 作為旁注,大量的構造函數參數是一種糟糕的代碼味道,這意味着該類可能有太多的責任,應該重構以更好地解決適當的關注點分離問題。

Setter 注入應該主要僅用於可以在類中分配合理默認值的可選依賴項。 否則,必須在代碼使用依賴項的任何地方執行非空檢查。 setter 注入的一個好處是 setter 方法使該類的對象可以在以后重新配置或重新注入。 因此,通過 JMX MBean 進行管理是 setter 注入的一個引人注目的用例。

使用對特定類最有意義的 DI 樣式。 有時,在處理您沒有源的第三方類時,選擇是為您做出的。 例如,如果第三方類不公開任何 setter 方法,則構造函數注入可能是 DI 的唯一可用形式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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