自訂轉換

以下 Spring Converter 實作範例將 `String` 轉換為自訂 `Email` 值物件

@ReadingConverter
public class EmailReadConverter implements Converter<String, Email> {

  public Email convert(String source) {
    return Email.valueOf(source);
  }
}

如果您撰寫的 `Converter` 其來源和目標類型為原生類型,我們無法判斷是否應將其視為讀取或寫入轉換器。將轉換器實例同時註冊為兩者可能會導致不良結果。例如,`Converter<String, Long>` 是不明確的,儘管在寫入時嘗試將所有 `String` 實例轉換為 `Long` 實例可能沒有意義。為了讓您強制基礎架構僅以一種方式註冊轉換器,我們提供了 `@ReadingConverter` 和 `@WritingConverter` 注釋,用於轉換器實作中。

轉換器需要明確註冊,因為實例不會從類別路徑或容器掃描中選取,以避免向轉換服務進行不必要的註冊以及由此類註冊產生的副作用。轉換器在 `CustomConversions` 中註冊,作為中央機制,允許根據來源和目標類型註冊和查詢已註冊的轉換器。

`CustomConversions` 隨附一組預先定義的轉換器註冊

  • JSR-310 轉換器,用於 `java.time`、`java.util.Date` 和 `String` 類型之間的轉換。

用於本機時間類型(例如 `LocalDateTime` 到 `java.util.Date`)的預設轉換器依賴系統預設時區設定,以在這些類型之間進行轉換。您可以註冊自己的轉換器來覆寫預設轉換器。

轉換器消除歧義

一般來說,我們會檢查 `Converter` 實作的來源和目標類型,以了解它們從哪裡轉換到哪裡。根據其中一個類型是否為底層資料存取 API 可以原生處理的類型,我們會將轉換器實例註冊為讀取或寫入轉換器。以下範例顯示寫入和讀取轉換器(請注意,差異在於 `Converter` 上限定詞的順序)

// Write converter as only the target type is one that can be handled natively
class MyConverter implements Converter<Person, String> { … }

// Read converter as only the source type is one that can be handled natively
class MyConverter implements Converter<String, Person> { … }