Beanlar bilan ishlash

All lectures for UZ purposes
Daraja, Dars
Mavjud

org.springframework.beans paketi JavaBeans sinf standarti asosida ishlaydi. JavaBean – bu argumentlarsiz boshlang'ich construktorga ega sinf bo'lib, nomlash konventsiyasiga rioya qiladi, bunda masalan bingoMadness nomidagi property uchun setBingoMadness(…) va getBingoMadness() nomli setter va getterlar bo'ladi. JavaBeans va spetsifikatsiya haqida koʻproq maʼlumot olish uchun javabeansni koʻrib chiqing.

Beans paketidagi muhim sinflardan biri BeanWrapper interfeysi va uning mos keluvchi implementatsiyasi (BeanWrapperImpl)dir. javadoc'da aytilganidek, BeanWrapper alohida yoki ommaviy tarzda property qiymatlarini o'rnatish va olish, property descriptor'larini olish va propertylarni so'roqlash uchun foydalanish imkonini beradi. Bundan tashqari, BeanWrapper nested propertylarni qo'llab-quvvatlaydi, bu esa sub-property uchun cheksiz chuqurlikdagi propertylarni o'rnatishga imkon beradi. BeanWrapper shuningdek, JavaBeans PropertyChangeListeners va VetoableChangeListenersni target sinfda qo'shimcha kodga ehtiyoj sezmasdan qo'shish imkoniyatini qo'llab-quvvatlaydi. So'nggi, ammo muhim xususiyatlaridan biri: BeanWrapper indekslangan propertylarni o'rnatishni qo'llab-quvvatlaydi. BeanWrapper odatda ilova kodi orqali to'g'ridan-to'g'ri ishlatilmaydi, balki DataBinder va BeanFactory orqali ishlatiladi.

BeanWrapper qanday ishlashini nomidan ham tushunish mumkin: u bean'ni o'rab olib, unga o'rnatish va olish kabi ma'lum operatsiyalarni bajaradi.

Asosiy va nested propertylarni o'rnatish va olish

Propertylarni o'rnatish va olish BeanWrapper ichida setPropertyValue va getPropertyValue ortiqcha yuklangan metodlari orqali amalga oshiriladi. Ularning Javadoc'ida batafsil ma'lumot berilgan. Quyida bu konventsiyalarning ba'zi misollari keltirilgan:

Jadval 11. Property misollari
Ifoda Izoh

name

namega ishora qiladi, bu getName() yoki isName() va setName(..) metodlariga mos keladi.

account.name

account ning name nested propertysiga ishora qiladi, bu (masalan) getAccount().setName() yoki getAccount().getName() metodlariga mos keladi.

account[2]

uchinchi indekslangan property account elementiga ishora qiladi. Indekslangan propertylar array, list yoki boshqa tabiiy ravishda tartiblangan kolleksiyalar turi bo'lishi mumkin.

account[COMPANYNAME]

Account Map propertiesidagi COMPANYNAME kaliti bilan indekslangan associative arrayning qiymatiga ishora qiladi.

(Agar siz BeanWrapper bilan to'g'ridan-to'g'ri ishlashni rejalashtirmasangiz, bu keyingi qism juda muhim emas. Agar siz faqat DataBinder va BeanFactory dan va ularning odatiy implementatsiyalaridan foydalansangiz, to'g'ridan-to'g'ri PropertyEditors ga o'tish kerak.)

Quyida ikkita sinf misoli BeanWrapper dan foydalanib propertylarni o'rnatish va olishni ko'rsatadi:

Java
public class Company {
    private String name;
    private Employee managingDirector;
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Employee getManagingDirector() {
        return this.managingDirector;
    }
    public void setManagingDirector(Employee managingDirector) {
        this.managingDirector = managingDirector;
    }
}
Kotlin
class Company {
    var name: String? = null
    var managingDirector: Employee? = null
}
Java
public class Employee {
    private String name;
    private float salary;
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getSalary() {
        return salary;
    }
    public void setSalary(float salary) {
        this.salary = salary;
    }
}
Kotlin
class Employee {
    var name: String? = null
    var salary: Float? = null
}

Quyidagi kod bo'laklari Company va Employees ni ishlatib hosil qilingan instance'larning ba'zi propertylarini olish va ulardan foydalanishni ko'rsatadi:

Java
BeanWrapper company = new BeanWrapperImpl(new Company());
// kompaniya nomini o'rnatish...
company.setPropertyValue("name", "Some Company Inc.");
// ... bu quyidagicha amalga oshirilishi ham mumkin:
PropertyValue value = new PropertyValue("name", "Some Company Inc.");
company.setPropertyValue(value);
// Yaxshi, endi direktor yaratib, uni kompaniyaga bog'laymiz:
BeanWrapper jim = new BeanWrapperImpl(new Employee());
jim.setPropertyValue("name", "Jim Stravinsky");
company.setPropertyValue("managingDirector", jim.getWrappedInstance());
// managingDirector uchun company orqali salaryni olish
Float salary = (Float) company.getPropertyValue("managingDirector.salary");
Kotlin
val company = BeanWrapperImpl(Company())
// kompaniya nomini o'rnatish...
company.setPropertyValue("name", "Some Company Inc.")
// ... bu quyidagicha amalga oshirilishi ham mumkin:
val value = PropertyValue("name", "Some Company Inc.")
company.setPropertyValue(value)
// Yaxshi, ko'ramiz, direktor yaratib, uni kompaniyaga bog'laymiz:
val jim = BeanWrapperImpl(Employee())
jim.setPropertyValue("name", "Jim Stravinsky")
company.setPropertyValue("managingDirector", jim.wrappedInstance)
// managingDirector uchun company orqali salaryni olish
val salary = company.getPropertyValue("managingDirector.salary") as Float?

Ichki PropertyEditor implementatsiyalari

Spring PropertyEditor kontseptsiyasidan obyekt va String oʻrtasida oʻzgartirishlarni amalga oshirish uchun foydalanadi. Propertylarni obyektning o'zi kabi ko'rsatishdan boshqa tarzda ko'rsatishi qulay bo'lishi mumkin. Masalan, Dateni inson ko'rinishi uchun o'qilishi mumkin bo'lgan shaklda (masalan, String: '2007-14-09') taqdim etish mumkin, lekin biz hali ham inson ko'rinishidagi shaklni asl sanaga qaytarishimiz mumkin (yoki, undan ham yaxshisi, inson ko'rinishidagi har qanday sanani asl Date obyektlariga qaytarishimiz mumkin). Bunday ishlash logikasiga maxsus java.beans.PropertyEditor tipidagi tahrirlovchilarni ro'yxatdan o'tkazib erishish mumkin. BeanWrapper yoki muqobilan, ma'lum bir IoC-konteynerida (avvalgi bobda eslatilganidek) maxsus tahrirlovchilarni ro'yxatdan o'tkazish, unga propertyni kerakli turga qanday o'zgartirishni bilish imkonini beradi. PropertyEditor haqida koʻproq maʼlumot olish uchun, Oracle'dan java.beans paketi boʻyicha javadocni koʻrib chiqing.

Spring'dagi propertyni tahrirlash xususiyatini qo'llashning bir necha misollari:

  • Beanlarning propertylarini o'rnatish PropertyEditor implementatsiyasi orqali amalga oshiriladi. Agar siz XML faylda deklaratsiya qilingan ba'zi bir bean uchun property qiymatini String turida ishlatsangiz, Spring (agar tegishli property setter parametri Class bo'lsa) ClassEditorni sinf parametrini Class obyektiga aylantirishga harakat qilish uchun ishlatadi.

  • Spring MVC ramkasi ichidagi HTTP so'rovning parametrlarini tahlil qilish PropertyEditor orqali amalga oshiriladi, bu barcha CommandControllerning subclass'larida qo'lda biriktiriladi.

Spring bir qator o'rnatilgan PropertyEditor implementatsiyalari ega, bu ishlashni osonlashtiradi. Bularning barchasi org.springframework.beans.propertyeditors paketida joylashgan. Ularning ko'plari (ammo hammasi emas, quyidagi jadvalda ko'rsatilganidek) BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi. Agar property editorini muayyan tarzda sozlash kerak bo'lsa, siz o'zingizning variantingizni ro'yxatdan o'tkazishingiz mumkin, bu sukut bo'yicha variantni almashtirish uchun. Quyidagi jadvalda Spring tomonidan taqdim etilgan turli PropertyEditor implementatsiyalari tasvirlangan:

Jadval 12. Ichki PropertyEditorimplementatsiyalari
Sinf Izoh

ByteArrayPropertyEditor

Baitu massivlar uchun tahrirlovchi. Stringlarni ularga mos keluvchi bayt ko'rinishlariga o'zgartiradi. BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi.

ClassEditor

Sinflarni ifodalovchi stringlarni real sinflarga o'zgartiradi va aksincha. Agar sinf topilmasa, IllegalArgumentExceptionni chiqaradi. BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi.

CustomBooleanEditor

Boolean propertylar uchun moslashtirilgan tahrirlovchi. BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi, ammo maxsus tahrirlovchi sifatida uning moslashtirilgan nusxasini ro'yxatdan o'tkazish orqali almashtirilishi mumkin.

CustomCollectionEditor

Kollektsiyalar uchun property tahrirlovchi, har qanday asl Collectionni maqsadli Collection turiga o'zgartiradi.

CustomDateEditor

To'g'rilangan java.util.Date property tahrirlovchi, maxsus DateFormatni qo'llab-quvvatlaydi. Sukut bo'yicha ro'yxatdan o'tmagan. Foydalanuvchi zaruratga ko'ra mos formatda ro'yxatdan o'tkazishi kerak.

CustomNumberEditor

Har qanday Number subklasslar, masalan Integer, Long, Float yoki Double uchun to'g'rilangan property tahrirlovchi. BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi, ammo maxsus tahrirlovchi sifatida uning moslashtirilgan nusxasini ro'yxatdan o'tkazish orqali almashtirilishi mumkin.

FileEditor

Stringlarni java.io.File obyektlariga o'zgartiradi. BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi.

InputStreamEditor

Bir yo'nalishli property tahrirlovchi bo'lib, u stringni qabul qiladi va (oraliq ResourceEditor va Resource orqali) InputStream yaratadi, shuning uchun InputStream propertylari string sifatida to'g'ridan-to'g'ri o'rnatilishi mumkin. E'tibor bering, sukut bo'yicha InputStream yopilmaydi. BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi.

LocaleEditor

Stringlarni Locale obyektlariga va aksincha o'zgartirishi mumkin (string formati - [language]_[country]_[variant], bu Locale ichidagi toString() metodiga o'xshaydi). Pastki chiziqning alternativasi sifatida bo'shliqlarni ajratgich sifatida qabul qiladi. BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi.

PatternEditor

Stringlarni java.util.regex.Pattern obyektlariga va aksincha o'zgartirishi mumkin.

PropertiesEditor

Stringlarni (java.util.Properties sinfi javadoc'ida belgilangan formatda) Properties obyektlariga o'zgartirishi mumkin. BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi.

StringTrimmerEditor

Stringlarni tahrirlaydigan property tahrirlovchi. Ixtiyoriy ravishda bo'sh stringni null qiymatiga aylantirishga imkon beradi. sukut bo'yicha ro'yxatdan o'tkazilmagan - foydalanuvchi tomonidan ro'yxatdan o'tkazilishi kerak.

URLEditor

Biror URL-manzilning string ko'rinishini real URL obyekti sifatida o'zgartirishi mumkin. BeanWrapperImpl tomonidan sukut bo'yicha ro'yxatdan o'tkaziladi.

Spring kerak bo'lishi mumkin bo'lgan property tahrirlovchilar uchun qidirish yo'lini o'rnatish uchun java.beans.PropertyEditorManagerdan foydalanadi. Qidirish yo'li sun.bean.editorsni ham o'z ichiga oladi, bu Font, Color va koʻpgina primitiv turlar uchun PropertyEditor implementatsiyalarini oʻz ichiga oladi. JavaBeans sinfining standart infratuzilmasi, agar ular o'zlari ishlov beradigan sinf bilan bir xil paketda joylashgan bo'lsa va shu sinf nomiga Editor qo'shilgan nom bilan bir xil bo'lsa, PropertyEditor sinflarini avtomatik ravishda aniqlaydi (aniq ro'yxatdan o'tkazishga ehtiyoj sezmasdan). Misol uchun, sizda quyidagi sinf va paket strukturasiga ega bo'lishingiz mumkin, bu yetarli bo'ladi, shunda SomethingEditor sinfi Something turidagi propertylar uchun PropertyEditor sifatida aniqlanadi va ishlatiladi.

com
  chank
    pop
      Something
      SomethingEditor // Something uchun PropertyEditor sinfi

Bu holda, shuningdek, JavaBeans sinfi BeanInfo standart mexanizmini (bir oz darajada bu yerda tavsiflangan) ishlatishingiz mumkin. Quyidagi misol BeanInfo mexanizmidan foydalanib, bir yoki bir nechta PropertyEditor instance'larini bog'liq sinf property'lariga aniq ro'yxatdan o'tkazish uchun foydalanadi:

com
  chank
    pop
      Something
      SomethingBeanInfo // Something uchun BeanInfo sinfi

Quyidagi SomethingBeanInfo sinfiga tegishli Java manba kodi CustomNumberEditorni Something sinfining age propertysi bilan bog'laydi:

Java
public class SomethingBeanInfo extends SimpleBeanInfo {
    public PropertyDescriptor[] getPropertyDescriptors() {
        try {
            final PropertyEditor numberPE = new CustomNumberEditor(Integer.class, true);
            PropertyDescriptor ageDescriptor = new PropertyDescriptor("age", Something.class) {
                @Override
                public PropertyEditor createPropertyEditor(Object bean) {
                    return numberPE;
                }
            };
            return new PropertyDescriptor[] { ageDescriptor };
        }
        catch (IntrospectionException ex) {
            throw new Error(ex.toString());
        }
    }
}
Kotlin
class SomethingBeanInfo : SimpleBeanInfo() {
    override fun getPropertyDescriptors(): Array<PropertyDescriptor> {
        try {
            val numberPE = CustomNumberEditor(Int::class.java, true)
            val ageDescriptor = object : PropertyDescriptor("age", Something::class.java) {
                override fun createPropertyEditor(bean: Any): PropertyEditor {
                    return numberPE
                }
            }
            return arrayOf(ageDescriptor)
        } catch (ex: IntrospectionException) {
            throw Error(ex.toString())
        }
    }
}

Maxsus PropertyEditor implementatsiyalarini ro'yxatdan o'tkazish

Bean propertylarini string qiymatlari sifatida o'rnatishda, Spring IoC konteyneri oxir-oqibat, bu stringlarni murakkab property turiga aylantirish uchun JavaBeans PropertyEditorning standart implementatsiyasidan foydalanadi. Spring bir nechta moslashtirilgan PropertyEditor implementatsiyalarini oldindan ro'yxatdan o'tkazadi (masalan, sinf nomini string sifatida ifodalab, uni Class obyektiga aylantirish uchun). Bundan tashqari, JavaBeans ning PropertyEditor uchun standart qidiruv mexanizmi PropertyEditorni nomlanganini toʻgʻri qilib qoʻyish va unga qoʻllab-quvvatlashni taʼminlaydigan sinf bilan bir xil paketga joylashtirishga imkon beradi, shunda u avtomatik ravishda topilishi mumkin.

Boshqa PropertyEditorsni ro'yxatdan o'tkazishga ehtiyoj tug'ilganda bir nechta mexanizmlar mavjud. Qo'lda foydalanishning eng sodda usuli, odatda qulay va tavsiya etilmaydi, BeanFactoryga havola mavjud bo'lsa, ConfigurableBeanFactory interfeysidagi registerCustomEditor() metodidan foydalanishdan iborat. Yana bir qulayroq mexanizm maxsus CustomEditorConfigurer nomli bean fabrikasi post-protsessoridan foydalanishni o'z ichiga oladi. Garchi BeanFactoryni amalga oshirish orqali bean fabrikasi post-protsessorlarini ishlatish mumkin bo'lmasa ham, CustomEditorConfigurer ichki property o'rnatishni o'z ichiga oladi, shuning uchun uni ApplicationContext bilan ishlatishni, uni boshqa har qanday bean sifatida joylashtirish mumkin bo'lgan holatlarda, kuchli tavsiya etamiz va u avtomatik topiladi va qo'llaniladi.

Barcha bean fabrikalari va ilova kontekstlari avtomatik ravishda property o'zgartirishlarni ishlashni qo'llash uchun BeanWrapperdan foydalanish tufayli bir qator ichki property tahrirlovchilarni qo'llaydi. Bundan tashqari, ApplicationContext resurslarni topishni ilova konteksti turiga moslashtirish uchun qo'shimcha tahrirlovchilarni almashtiradi yoki qo'shadi.

JavaBeans sinfining standart PropertyEditor instance'lari string sifatida ifodalangan property qiymatlarini haqiqiy murakkab property turiga aylantirish uchun ishlatiladi. CustomEditorConfigurer dan foydalanish orqali ApplicationContext ga qo'shimcha PropertyEditor instance'larini qo'llab-quvvatlashni qulay tarzda qo'shishingiz mumkin.

Quyidagi misolda, ExoticType maxsus sinfi va DependsOnExoticType sinfi belgilangan boʻlib, unga property sifatida ExoticType oʻrnatilishi kerak:

Java
package example;
public class ExoticType {
    private String name;
    public ExoticType(String name) {
        this.name = name;
    }
}
public class DependsOnExoticType {
    private ExoticType type;
    public void setType(ExoticType type) {
        this.type = type;
    }
}
Kotlin
package example
class ExoticType(val name: String)
class DependsOnExoticType {
    var type: ExoticType? = null
}

Agar hammasi to'g'ri o'rnatilgan bo'lsa, property tipiga string qiymatini tayinlashimiz kerak, bu PropertyEditorni haqiqiy ExoticType instance'iga aylantiradi. Quyidagi bean ta'rifi bu munosabatni qanday o'rnatishni ko'rsatadi:

<bean id="sample" class="example.DependsOnExoticType">
    <property name="type" value="aNameForExoticType"/>
</bean>

PropertyEditor implementatsiyasi quyidagicha ko'rinishi mumkin:

Java
// string ko'rinishini ExoticType obyektiga o'zgartiradi
package example;
public class ExoticTypeEditor extends PropertyEditorSupport {
    public void setAsText(String text) {
        setValue(new ExoticType(text.toUpperCase()));
    }
}
Kotlin
// string ko'rinishini ExoticType obyektiga o'zgartiradi
package example
import java.beans.PropertyEditorSupport
class ExoticTypeEditor : PropertyEditorSupport() {
    override fun setAsText(text: String) {
        value = ExoticType(text.toUpperCase())
    }
}

Va nihoyat, quyidagi misolda yangi PropertyEditorni ApplicationContext da ro'yxatdan o'tkazish va uni kerakli vaqtda foydalana olish imkoniyatini koʻrsatadi:

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="customEditors">
        <map>
            <entry key="example.ExoticType" value="example.ExoticTypeEditor"/>
        </map>
    </property>
</bean>
PropertyEditorRegistrar dan foydalanish

Spring konteyneriga property tahrirlovchilarni ro'yxatdan o'tkazishning boshqa bir mexanizmi PropertyEditorRegistrar ni yaratish va undan foydalanishdir. Ushbu interfeys ayniqsa, bir xil property tahrirlovchilar to'plamini bir necha turli vaziyatlarda ishlatish kerak bo'lsa, foydalidir. Siz bir nechta mos keluvchi ro'yxatdan o'tkazuvchini (registrar) yozishingiz va uni har bir holatda qayta ishlatishingiz mumkin. PropertyEditorRegistrar instance'lari Spring'ning BeanWrapper (va DataBinder) tomonidan amalga oshirilgan PropertyEditorRegistry interfeysi bilan birgalikda ishlaydi. PropertyEditorRegistrar instance'lari ayniqsa CustomEditorConfigurer bilan birgalikda, unga setPropertyEditorRegistrars(..) propertysini taqdim etadigan holda foydalidirlar. PropertyEditorRegistrarni CustomEditorConfigurer ga qo'shilgan holda, ularning funksiyasi DataBinder va Spring MVC kontrollerlar bilan birgalikda osongina ishlatilishi mumkin. Bundan tashqari, bu maxsus tahrirlovchilarda sinxronlash zaruratini bartaraf etishga imkon beradi: PropertyEditorRegistrar bin yaratishga harakat qilganda har safar yangi PropertyEditor instance'larini yaratishi kutiladi.

Quyidagi misolda maxsus PropertyEditorRegistrar implementatsiyasini qanday yaratish mumkinligi ko'rsatilgan:

Java
package com.foo.editors.spring;
public final class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        // yangi PropertyEditor instance'larini yaratish kutiladi
        registry.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());
        // bu holatda kerak bo'lgancha ko'plab maxsus property tahrirlovchilarni ro'yxatdan o'tkazishingiz mumkin...
    }
}
Kotlin
package com.foo.editors.spring
import org.springframework.beans.PropertyEditorRegistrar
import org.springframework.beans.PropertyEditorRegistry
class CustomPropertyEditorRegistrar : PropertyEditorRegistrar {
    override fun registerCustomEditors(registry: PropertyEditorRegistry) {
        // yangi PropertyEditor instance'larini yaratish kutiladi
        registry.registerCustomEditor(ExoticType::class.java, ExoticTypeEditor())
        // bu holatda kerak bo'lgancha ko'plab maxsus property tahrirlovchilarni ro'yxatdan o'tkazishingiz mumkin...
    }
}

org.springframework.beans.support.ResourceEditorRegistrarda PropertyEditorRegistrar implementatsiyasining misolini ko'ring. E'tibor bering, u registerCustomEditors(…) metodining implementatsiyasida har bir property tahrirlovchini yangi nusxalarini yaratadi.

Quyidagi misolda CustomEditorConfigurerni qanday sozlash va unga CustomPropertyEditorRegistrardan nusxa olib kelish ko'rsatilgan:

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="propertyEditorRegistrars">
        <list>
            <ref bean="customPropertyEditorRegistrar"/>
        </list>
    </property>
</bean>
<bean id="customPropertyEditorRegistrar"
    class="com.foo.editors.spring.CustomPropertyEditorRegistrar"/>

Va nihoyat (va bu bobning mavzusidan biroz cheklangan holda), Spring'dan veb-ramka MVC'dan foydalanadiganlar uchun, PropertyEditorRegistrarni web loyihalarda foydalanish juda qulay bo'lishi mumkin. Quyidagi misolda PropertyEditorRegistrar'dan @InitBinder metodiga implementatsiyada foydalanilgan:

Java
@Controller
public class RegisterUserController {
    private final PropertyEditorRegistrar customPropertyEditorRegistrar;
    RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) {
        this.customPropertyEditorRegistrar = propertyEditorRegistrar;
    }
    @InitBinder
    void initBinder(WebDataBinder binder) {
        this.customPropertyEditorRegistrar.registerCustomEditors(binder);
    }
    // foydalanuvchi ro'yxatdan o'tkazish bilan bog'liq boshqa metodlar
}
Kotlin
@Controller
class RegisterUserController(
    private val customPropertyEditorRegistrar: PropertyEditorRegistrar) {
    @InitBinder
    fun initBinder(binder: WebDataBinder) {
        this.customPropertyEditorRegistrar.registerCustomEditors(binder)
    }
    // foydalanuvchi ro'yxatdan o'tkazish bilan bog'liq boshqa metodlar
}

Bu uslubda PropertyEditorni ro'yxatdan o'tkazish kodni soddalashtirishi mumkin (metod @InitBinder implementatsiyasi bor-yo'g'i bir qatorni tashkil etadi) va PropertyEditorni ro'yxatdan o'tkazish uchun mavjud umumiy kodni sinfga inkapsullash va keyin uni bir nechta kontrollerlar tomonidan foydalanishga imkon berishi mumkin.

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION