spring-boot轉(zhuǎn)換服務(wù)組件剖析

前言
今天要分享的內(nèi)容原本是要昨天分享的,具體原因昨天也說過了,雖然昨天沒分享成,但是昨天還是有意外收獲的,特別是關(guān)于converter的相關(guān)內(nèi)容,瞬間就讓我搞清楚了converter的用法和場景,所以這樣來說,其實今天的內(nèi)容算是對昨天內(nèi)容的延申和擴展。
好了,廢話不多說,下面我們直接看converter的相關(guān)內(nèi)容。
轉(zhuǎn)換組件
轉(zhuǎn)換組件算是spring boot的另一塊比較系統(tǒng),而且也比較通用的內(nèi)容,所以在剖析converter之前,我們有必要先看下轉(zhuǎn)換服務(wù)ConversionService,以及它的小伙伴,當(dāng)然其中也包括我們的converter。
ConversionService
這里我們說的轉(zhuǎn)換組件其實指的是ConversionService,它是spring為我們提供的類型轉(zhuǎn)換接口,通過調(diào)用convert(Object, Class)方法就可以實現(xiàn)一個類型到另一個類型的完美轉(zhuǎn)換,而且更重要的是,它是線程安全的:

與此相關(guān)的還有四個接口,一個是GenericConverter,一個是Converter<S, T>,還有一個是ConfigurableConversionService,最后一個是ConverterRegistry,我們先來說下這幾個接口的關(guān)系,首先最基本的當(dāng)然是ConversionService,它是所有轉(zhuǎn)換服務(wù)類的基類接口,它為我們提供了四個基本方法:
判斷是否可以進行類型轉(zhuǎn)換
boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType);
判斷是否可以進行類型轉(zhuǎn)換。和第一個方法類似,入?yún)⒂兴煌?/section>
boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType);
進行類型轉(zhuǎn)換,返回目標(biāo)類型的實例
<T> T convert(@Nullable Object source, Class<T> targetType);
進行類型轉(zhuǎn)換,和上一個方法作用相同,只是這里返回的是 Object,當(dāng)然入?yún)⒁灿兴煌?/section>
Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType);
但是僅有這四個基本方法還不夠,所以spring boot引入了ConverterRegistry接口。
ConverterRegistry
ConverterRegistry接口的主要作用就是實現(xiàn)最轉(zhuǎn)換器的管理,主要包括往ConversionService中添加轉(zhuǎn)換器。因為ConversionService不可能只提供某幾種特定的類型轉(zhuǎn)換,為了能夠?qū)崿F(xiàn)轉(zhuǎn)換器的擴展,同時對轉(zhuǎn)換器實現(xiàn)管理,spring boot引入了ConverterRegistry(轉(zhuǎn)換器注冊接口):

這個接口為我們提供了五個方法,分為三類:
添加轉(zhuǎn)換器
void addConverter(Converter<?, ?> converter);
// 也是一個新增接口,入?yún)⒉灰粯?/span>
<S, T> void addConverter(Class<S> sourceType, Class<T> targetType, Converter<? super S, ? extends T> converter);
// 第三種轉(zhuǎn)換器新增
void addConverter(GenericConverter converter);
添加轉(zhuǎn)換器工廠
void addConverterFactory(ConverterFactory<?, ?> factory);
移除轉(zhuǎn)換器
void removeConvertible(Class<?> sourceType, Class<?> targetType);
在上面這幾個方法中,sourceType表示原始類型,targetType表示目標(biāo)類型,converter就是我們的轉(zhuǎn)換器,這里轉(zhuǎn)換器主要有兩種,一種是直接繼承了Converter的轉(zhuǎn)換器,另一種就是基于GenericConverter實現(xiàn)的類型轉(zhuǎn)換,所以下面我們就分享下這兩個接口的相關(guān)內(nèi)容。
converter和GenericConverter
這里的converter類型的轉(zhuǎn)換器是最常用的轉(zhuǎn)換器類型,比如我們昨天演示的String轉(zhuǎn)日期的轉(zhuǎn)換類,就屬于這種:

GenericConverter本身也是一個接口,而且是獨立的,它不同于converter:

它有兩個核心方法:
獲取轉(zhuǎn)換類型
Set<ConvertiblePair> getConvertibleTypes();
這里的ConvertiblePair是GenericConverter接口的一個內(nèi)部類,它是保存sourceType和targetType的容器:

類型轉(zhuǎn)換
Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
們昨天分享的內(nèi)容可以看出來,ConversionService服務(wù)主要的作用就是進行數(shù)據(jù)類型轉(zhuǎn)換,通常情況下,我們并不需要實現(xiàn)ConversionService接口,而是實現(xiàn)GenericConverter轉(zhuǎn)換器即可,而且從昨天我們啟動測試的情況來看,基本上所有的轉(zhuǎn)換器都是基于GenericConverter實現(xiàn)的:

ConverterRegistry接口對這兩種接口都提供了支持,可以直接對這兩種轉(zhuǎn)換器進行新增和移出。
ConfigurableConversionService
這里的ConfigurableConversionService接口其實是ConversionService接口和ConverterRegistry接口的合體,它直接繼承了這兩個接口,具備這兩個接口的能力,而且從名字也可以看出來,它應(yīng)該是用來配置我們的轉(zhuǎn)換服務(wù)的。

總結(jié)
今天主要是梳理了和ConversionService相關(guān)的接口以及接口的方法,算是對昨天內(nèi)容的補充和延申,但是ConversionService的相關(guān)內(nèi)容還比較多,所以我打算分兩到三次分享,這樣我們就可以更細致地展開,了解的也更深入。
好了,關(guān)于converter的相關(guān)內(nèi)容我們暫時先說這么多,明天我們再結(jié)合run方法看下ConversionService以及它的小伙伴的初始化過程。
