Spring 3-də core.convert
paketi təqdim edildi ki, bu da ümumi tip dəyişmə sistemi təmin edir. Sistem, mənbə kodunun tip dəyişməsini həyata keçirmək üçün SPI (xidmət təmin edici interfeysi) və API interfeysi təyin edir. Spring konteynerində bu sistemi xüsusiyyətlərin istənilən tiplərini təmin etmək üçün hissələrin dəyər sətirlərinin çevrilməsi üçün PropertyEditor
əvəzinə istifadə edə bilərsiniz. Eyni zamanda, tip dəyişmənin tələb olunduğu hər hansı tətbiqin hər hansı bir yerində bu API interfeysini də istifadə edə bilərsiniz.
SPI interfeysi Converter
Tip dəyişmə məntiqini həyata keçirmək üçün SPI interfeysi sadə və ciddi tipli, interfeys təyinində göstərildiyi kimi:
package org.springframework.core.convert.converter;
public interface Converter<S, T> {
T convert(S source);
}
Öz çevricinizi yaratmaq üçün Converter
interfeysini həyata keçirərək S
vasitəsilə çevirdiyiniz tip və T
ilə çevirdiyiniz tip kimi parametrizə edin. Belə çevriciləri də asanlıqla istifadə edə bilərsiniz, əgər S
kolleksiyasını və ya massivini T
kolleksiyası və ya massivinə çevirmək lazımdırsa, əgər ki, array və ya kolleksiya çevricisi də qeydiyyatdan keçmişdirsə (bu həmçinin DefaultConversionService
vasitəsilə standart olaraq təmin edilir).
Hər bir convert(S)
çağırışı üçün mənbə arqumenti heç vaxt boş (null) deyil. Sizin Converter
dəyişmə uğurlu olmadığında hər hansı bir yoxlanılmayan istisna verə bilər. Xüsusilə, o, səhv mənbə dəyərini bildirmək üçün IllegalArgumentException
istisnası verməlidir. Converter
implementasiyanızın təhlukəsiz axınlı olmasına diqqət edin.
core.convert.support
paketində bir neçə rahat çevrici həyata keçirilməsi təmin edilib. Bunlara sətirlərdən rəqəmlərə və digər ümumi tiplərə çevricilər daxildir. Aşağıdakı siyahı Converter
-in tipik bir həyata keçirilməsi olan StringToInteger
sinifini göstərir:
package org.springframework.core.convert.support;
final class StringToInteger implements Converter<String, Integer> {
public Integer convert(String source) {
return Integer.valueOf(source);
}
}
ConverterFactory
istifadə edilməsi
Bütün siniflər iyerarxiyası üçün tip çevirmə məntiqini mərkəzləşdirmək vacibdirsə (məsələn, String
obyektlərindən Enum
obyektlərinə çevirmə zamanı), ConverterFactory
həyata keçirə bilərsiniz, aşağıdakı nümunədə göstərildiyi kimi:
package org.springframework.core.convert.converter;
public interface ConverterFactory<S, R> {
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
S-ni çevirdiyiniz tip olaraq, R-ni isə çevrilə biləcək siniflər diapazonunu müəyyən edən əsas tip olaraq parametrizə edin. Daha sonra getConverter(Class<T>)
həyata keçirin, harada ki, T R-nin subclassıdır.
Məsələn, StringToEnumConverterFactory
nəzər salaq:
package org.springframework.core.convert.support;
final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
return new StringToEnumConverter(targetType);
}
private final class StringToEnumConverter<T extends Enum> implements Converter<String, T> {
private Class<T> enumType;
public StringToEnumConverter(Class<T> enumType) {
this.enumType = enumType;
}
public T convert(String source) {
return (T) Enum.valueOf(this.enumType, source.trim());
}
}
}
GenericConverter
istifadə edilməsi
Əgər mürəkkəb Converter
implementasiyasına ehtiyacınız varsa, GenericConverter
interfeysindən istifadə edin. GenericConverter
daha çevik, lakin Converter
dən daha az ciddi tipli imzaya malikdir və bir neçə mənbə və hədəf tipi arasında çevirməni dəstəkləyir. Bundan əlavə, GenericConverter
mənbə və hədəf sahəsinin kontekstini istifadə üçün təqdim edir. Bu kontekst, sahə anotasiya əsasında və ya sahənin imzasında elan olunan ümumi məlumatlar əsasında tip çevirməyə imkan verir. Aşağıdakı siyahı GenericConverter
interfeysinin təyinini göstərir:
package org.springframework.core.convert.converter;
public interface GenericConverter {
public Set<ConvertiblePair> getConvertibleTypes();
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
GenericConverter
-i həyata keçirmək üçün getConvertibleTypes()
funksiyası dəstəklənən mənbə→hədəf tip cütlərini qaytarmalıdır. Daha sonra convert(Object, TypeDescriptor, TypeDescriptor)
həyata keçirin ki, çevirmə məntiqi əlavə olunsun. Mənbə TypeDescriptor
mənbə sahəsindəki şəkildən tipik qiymətə giriş imkanı təqdim edir. Hədəf TypeDescriptor
isə çevrilmiş qiyməti təyin edilməsi gərək olan sahəyə giriş imkanı yaradır.
Yaxşı bir GenericConverter
nümunəsi Java massivini kolleksiyaya çevirən bir çevricidir. Belə bir ArrayToCollectionConverter
hədəf kolleksiyasının tip elementini təyin etmək üçün kolleksiya tipini bildirən sahənin öz-özünü təhlilini yerinə yetirir. Bu, kolleksiyanın hədəf sahəyə təyin olunmazdan əvvəl mənbə massivinin hər bir elementini kolleksiya element tipinə çevirmək imkanı verir.
GenericConverter
daha mürəkkəb bir SPI interfeysi olduğuna görə, onu yalnız zərurət olduqda istifadə etməliyik. Tip dəyişmə üçün əsas ehtiyaclar üçün
Converter
və ya
ConverterFactory
istifadə edin.
ConditionalGenericConverter
istifadə edilməsi
Bəzən Converter
-in yalnız müəyyən şərt yerinə yetirildikdə işə salınması lazım olur. Məsələn, hədəf sahədə müəyyən anotasiya varsa, Converter
-i işə salmağınız lazım ola bilər və ya hədəf sinifdə müəyyən bir metod müəyyən olunarsa (məsələn, static valueOf
metodu), həmin Converter
-i işə salmaq lazım ola bilər. ConditionalGenericConverter
belə xüsusi uyğunluq kriteriyalarını təyin etməyə imkan verən GenericConverter
və ConditionalConverter
interfeyslərinin birləşməsidir:
public interface ConditionalConverter {
boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}
public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter {
}
Yaxşı bir ConditionalGenericConverter
nümunəsi, qalıcı bir obyektin identifikatorunu obyektin göstəricisinə çevirən IdToEntityConverter
-dir. Belə bir IdToEntityConverter
yalnız hədəf obyekt tipi statik axtarış metodu (məsələn, findAccount(Long)
) elan edirsə, uyğun ola bilər. matches(TypeDescriptor, TypeDescriptor)
realizasiyasında həmin axtarış metodunun yoxlanışını edə bilərsiniz.
ConversionService
API
ConversionService
proqram işləmə zamanı mənbə kodunun tip dəyişmə məntiqini həyata keçirmək üçün birləşmiş bir API təyin edir. Çevricilər adətən növbəti fasad interfeysindən işə salınır:
package org.springframework.core.convert;
public interface ConversionService {
boolean canConvert(Class<?> sourceType, Class<?> targetType);
<T> T convert(Object source, Class<T> targetType);
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
Çoğu ConversionService
realizasiyası eyni zamanda çevriciləri qeyd etmək üçün SPI interfeys təqdim edən ConverterRegistry
-i həyata keçirir. Daxili olaraq ConversionService
realizasiyası qeydiyyatdan keçmiş çevricilərinə tip dəyişmə məntiqini həyata keçirmək üçün nümayəndəlik edir.
ConversionService
-in etibarlı realizasiyası core.convert.support
paketində təqdim edilir. GenericConversionService
əksər mühitlər üçün uyğun ümumi məqsədli bir realizasiyadır. ConversionServiceFactory
ümumi ConversionService
konfiqurasiyalarını yaratmaq üçün rahat bir fabrik təqdim edir.
ConversionService
konfiqurasiyası
ConversionService
bir halda saxlanılan obyekt deyil, hansı ki, tətbiq işə salındıqda yaradılır və müxtəlif axınlar arasında paylaşılır. Spring tətbiqində ConversionService
oxşar tətbiqçinin hər bir Spring konteyneri (və ya ApplicationContext
) üçün konfiqurasiya edilir. Spring bu ConversionService
-i müəyyən edir və hər dəfə çərçivə tip dəyişməsi etməsi lazım olduqda istifadə edir. Həmçinin, bu ConversionService
-i istənilən birinizə dərhal daxil edə bilərsiniz.
ConversionService
qeydiyyatdan keçməmişsə, o zaman
PropertyEditor
-ə əsaslanan orijinal sistem istifadə olunur.
Spring-də standart bir ConversionService
qeydiyyatdan keçirmək üçün aşağıdakı bean təyinini id
kimi conversionService
göstərərək əlavə edin:
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean"/>
Standart ConversionService
sətirlər, rəqəmlər, enumlar, kolleksiyalar, xəritələr və digər yaygın tipləri çevirmə qabiliyyətinə malikdir. Varsayılan çevriciləri öz xüsusi çevricilərinizlə tamamlamaq və ya əvəz etmək üçün converters
əmlakını təyin edin. Əmlak dəyərləri hər hansı bir Converter
, ConverterFactory
və ya GenericConverter
interfeysini həyata keçirə bilər.
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="example.MyCustomConverter"/>
</set>
</property>
</bean>
Spring MVC tətbiqində ConversionService
tez-tez istifadə olunur.
Bəzi hallarda çevirmə zamanı formatlaşdırmadan istifadə etmək olar.
ConversionService
-in proqramlı istifadəsi
ConversionService
nümunəsi ilə düyməli şəkildə işləmək üçün, onu başqa hər hansı bir bean kimi daxil edin. Aşağıdakı nümunə, bunu necə edəcəyinizi göstərir:
@Service
public class MyService {
public MyService(ConversionService conversionService) {
this.conversionService = conversionService;
}
public void doIt() {
this.conversionService.convert(...)
}
}
@Service
class MyService(private val conversionService: ConversionService) {
fun doIt() {
conversionService.convert(...)
}
}
Çoğu hallarda, convert
metodunu istifadə edərək, targetType
təyin etməklə kifayətlənə bilərsiniz, ancaq o, daha mürəkkəb tiplərlə, məsələn, parametrlənmiş elementin kolleksiyası ilə işləməyəcək. Məsələn, Integer
tipli List
-i String
tipli List
-ə çevirmək lazımdırsa, mənbə və hədəf tiplərinin formal təyinini təqdim etməlisiniz.
Xoşbəxtlikdən, TypeDescriptor
bunu asanlıqla həyata keçirmək üçün müxtəlif seçimlər təqdim edir, aşağıdakı nümunədə göstərildiyi kimi:
DefaultConversionService cs = new DefaultConversionService();
List<Integer> input = ...
cs.convert(input,
TypeDescriptor.forObject(input), // List<Integer> tipli təsvir
TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(String.class)));
val cs = DefaultConversionService()
val input: List<Integer> = ...
cs.convert(input,
TypeDescriptor.forObject(input), // List<Integer> tipli təsvir
TypeDescriptor.collection(List::class.java, TypeDescriptor.valueOf(String::class.java)))
Qeyd edək ki, DefaultConversionService
əksər mühitlər üçün uyğun olan çevriciləri avtomatik qaydada qeyd edir. Bunlara kolleksiya çevriciləri, skalar çevricilər və Object-to-String
əsas çevriciləri daxildir. Eyni çevriciləri herhangi bir ConverterRegistry
-də DefaultConversionService
sinfinin statik addDefaultConverters
metodu ilə qeyd edə bilərsiniz.
Dəyər tipləri üçün çevricilər massivlər və kolleksiyalar üçün təkrar istifadə olunur, ona görə də Collection
tipi S
ilə Collection
tipi T
arasında çevrici yaratmağa ehtiyac yoxdur, əgər standart kolleksiya emalı uyğun olacaqsa.
GO TO FULL VERSION