Spring Boot中使用record四種簡化用法

banq發表於2024-05-25

Java中引入的Record型別可以透過壓縮同原始碼來幫助我們提高可讀性和表現力的幾個場景。

1、在控制器中使用Record
通常,Spring Boot控制器使用簡單的POJO 類進行操作,這些類透過網路將資料傳回客戶端。例如,檢視這個簡單的控制器端點,它返回作者列表,包括他們的書籍:

@GetMapping(<font>"/authors")
public List<Author> fetchAuthors() {
  return bookstoreService.fetchAuthors();
}

在這裡,Author與 Book可以是POJO 的簡單資料載體,用record是這樣:

public record Book(String title, String isbn) {}
public record Author(String name, String genre, List<Book> books) {}

就是這樣!Jackson 庫(Spring Boot 中的預設 JSON 庫)會自動將 Author/Book 型別的例項轉換為 JSON。

2、模板中用Record
Thymeleaf 可能是 Spring Boot 應用程式中使用最多的模板引擎。Thymeleaf 頁面(HTML 頁面)通常由 POJO 類承載的資料填充,這意味著 Java 記錄也能正常工作。

讓我們來看看前面的 Author 和 Book 記錄以及下面的控制器端點:

@GetMapping(<font>"/bookstore")
public String bookstorePage(Model model) {
  
  model.addAttribute(
"authors",
  bookstoreService.fetchAuthors());
  
  return
"bookstore";
}

透過 fetchAuthors() 返回的 List<Author> 被儲存在模型中名為 authors 的變數下。該變數用於填充 bookstore.html,如下所示:

...
<ul th:each=<font>"author : ${authors}">
  <li th:text=
"${author.name} + ' (' + ${author.genre} + ')'" />
  <ul th:each=
"book : ${author.books}">
    <li th:text=
"${book.title}" />
  </ul>
</ul>
...

程式碼:Java Coding Problems SE.

3、使用Record進行配置
假設在 application.properties 中有以下兩個屬性(也可以用 YAML 表示):

bookstore.bestseller.author=Joana Nimar
bookstore.bestseller.book=Prague history

Spring Boot 透過 @ConfigurationProperties 將此類屬性對映到 POJO。但也可以使用記錄。例如,這些屬性可以如下方式對映到 BestSellerConfig 記錄:

@ConfigurationProperties(prefix = <font>"bookstore.bestseller")
public record BestSellerConfig(String author, String book) {}

接下來,在 BookstoreService(典型的 Spring Boot 服務)中,我們可以注入 BestSellerConfig 並呼叫其訪問器:

@Service
public class BookstoreService {
  
  private final BestSellerConfig bestSeller;

  public BookstoreService(BestSellerConfig bestSeller) {
    this.bestSeller = bestSeller;
  }
  
  public String fetchBestSeller() {
     return bestSeller.author() + <font>" | " + bestSeller.book();
  }
}

程式碼: bundled code


4、Record和依賴注入
在前面的示例中,我們使用 SpringBoot 提供的典型機制--透過建構函式進行依賴注入(也可以透過 @Autowired 進行)--將 BookstoreService 服務注入到 BookstoreController 中:

@RestController
public class BookstoreController {
  
  private final BookstoreService bookstoreService;
  
  public BookstoreController(BookstoreService bookstoreService) {
    this.bookstoreService = bookstoreService;
  }
  
  @GetMapping(<font>"/authors")
  public List<Author> fetchAuthors() {
    return bookstoreService.fetchAuthors();
  }
}


但是,我們可以透過將其改寫為記錄record來壓縮這個類,如下所示:

@RestController
public record BookstoreController(BookstoreService bookstoreService) {
  
  @GetMapping(<font>"/authors")
  public List<Author> fetchAuthors() {
    return bookstoreService.fetchAuthors();
  }
}

該記錄record的規範建構函式將與我們的顯式建構函式相同。

程式碼: GitHub.

相關文章