JavaRush /Kurslar /All lectures for UZ purposes /Spring Expression Language (SpEL) Ifoda Tili

Spring Expression Language (SpEL) Ifoda Tili

All lectures for UZ purposes
Daraja, Dars
Mavjud

Spring Expression Language (qisqacha - "SpEL") – bu kuchli ifoda tili bo'lib, dastur ishlayotgan paytda obyektlar grafi bilan so'rovlar va manipulyatsiyalarni qo'llab-quvvatlaydi. Tilning sintaksisi Unified EL ga o'xshaydi, lekin qo'shimcha imkoniyatlarni taklif qiladi, birinchi navbatda metodlarni chaqirish va asosiy string shablonlash funksiyalari.

Java uchun bir necha boshqa ifoda tillari mavjud bo'lsa-da - OGNL, MVEL, JBoss EL va boshqalar - Spring Expression Language ifoda tili Spring hamjamiyatiga tegishli qo'llab-quvvatlash bilan yagona ifoda tilini taqdim etish uchun yaratilgan, bu Spring portfeli barcha mahsulotlarida ishlatilishi mumkin. Tilning xususiyatlari Spring portfelidagi loyihalarning talablariga, jumladan, Spring Tools for Eclipse dagi kodni avtomatik tugatishni qo'llab-quvvatlash uchun vositalarga bo'lgan talablariga asoslanadi. Shu bilan birga, SpEL texnologiyaga bog'liq bo'lmagan API interfeysiga asoslangan bo'lib, agar kerak bo'lsa, boshqa ifoda tili amalga oshirilishini integratsiya qilishga imkon beradi.

Garchi SpEL Spring portfelidagi ifodalarni hisoblash uchun asosiy mahsulot bo'lsa-da, u Spring bilan bevosita bog'liq emas va mustaqil ravishda ishlatilishi mumkin. Mustaqillikni namoyish qilish uchun ushbu bobdagi ko'plab misollar SpEL ni mustaqil ifoda tili sifatida ishlatgan holda ko'rsatadi. Bu parser kabi qator yuklash infratuzilmasi sinflarini yaratishni talab qiladi. Ko'pgina Spring foydalanuvchilariga ushbu infratuzilma bilan ishlash kerak emas, shuning uchun ular faqat ifoda satrlarini hisoblash uchun yaratishi mumkin. Bunday tipik foydalanish misoliga XML yoki annotatsiyalarga asoslangan bean ta'riflarni yaratishda SpEL integratsiyasi kiradi.

Ushbu bobda ifoda tilining xususiyatlari, uning API interfeysi va til sintaksisi ko'rib chiqiladi. Ba'zi joylarda ifodalarni hisoblash uchun maqsad obyektlari sifatida Inventor va Society sinflari ishlatiladi. Ushbu sinflarning e'lonlari va ularni to'ldirish uchun ishlatiladigan ma'lumotlar bob oxirida keltirilgan.

Ifoda tili quyidagi funksiyalarni qo'llab-quvvatlaydi:

  • Literal ifodalar (literallar);

  • Boolean operatorlari va munosabatlar operatorlari;

  • Regulyar ifodalar;

  • Class-ifodalar;

  • Propertylar, massivlar, ro'yxatlar va associativ massivlar bilan kirish;

  • Metodlarga murojaat qilish;

  • Munosabatlar operatorlari;

  • Assign qilish;

  • Konstruktorlarni chaqirish;

  • Beanlarga havolalar;

  • Massivning yaratilishi;

  • Ichki ro'yxatlar;

  • Ichki associativ massivlar;

  • Ternary operator;

  • O'zgaruvchilar;

  • Iste'molchi belgilagan funksiyalar;

  • Kollektsiyalarning proyeksiyasi;

  • Kollektsiyalarning tanlovi;

  • Shablonli ifodalar.

Hisoblash

Ushbu bo'lim SpEL interfeysi va ularning ifoda tilidan oddiy foydalanishni tanishtiradi.

Quyidagi kod SpEL API interfeysidan Hello World literali satr ifodasini baholash uchun foydalanadi.

Java
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'Hello World'"); 
String message = (String) exp.getValue();
  1. Xabar o'zgaruvchisi qiymati 'Hello World' ga teng.
Kotlin
val parser = SpelExpressionParser()
val exp = parser.parseExpression("'Hello World'") 
val message = exp.value as String
  1. Xabar o'zgaruvchisi qiymati 'Hello World' ga teng.

SpEL sinflari va interfeyslari, ehtimol siz foydalanadiganlar, org.springframework.expression paketida va uning qo'shimcha paketlarida joylashgan, masalan, spel.support.

ExpressionParser interfeysi ifodani tahlil qilish uchun mas'ul hisoblanadi. Oldingi misolda ifoda satri bir qator literali bo'lib, uni o'rab oluvchi yakka tirnokchalar bilan belgilanadi. Expression interfeysi avval tahlil qilingan ifoda satrini baholash uchun mas'ul hisoblanadi. ParseException va EvaluationException istisnolari mos ravishda parser.parseExpression va exp.getValue chaqirilganda yaratilishi mumkin.

SpEL keng doiradagi funktsiyalarni qo'llab-quvvatlaydi, masalan, metodlarni chaqirish, propertylarga kirish va konstruktorlarni chaqirish.

Quyidagi misolda metodni chaqirishda biz concat metodini qo'llaymiz:

Java
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.concat('!')"); 
String message = (String) exp.getValue();
  1. message o'zgaruvchisi endi 'Hello World!' ga teng bo'ldi.
Kotlin
val parser = SpelExpressionParser()
val exp = parser.parseExpression("'Hello World'.concat('!')") 
val message = exp.value as String
  1. message o'zgaruvchisi endi 'Hello World!' ga teng bo'ldi.

Quyidagi misolda JavaBean property chaqiriladi:

Java
ExpressionParser parser = new SpelExpressionParser();
// 'getBytes()' ga murojaat qiladi
Expression exp = parser.parseExpression("'Hello World'.bytes"); 
byte[] bytes = (byte[]) exp.getValue();
  1. Ushbu satr literalni baytli massivga aylantiradi.
Kotlin
val parser = SpelExpressionParser()
// 'getBytes()' ga murojaat qiladi
val exp = parser.parseExpression("'Hello World'.bytes") 
val bytes = exp.value as ByteArray
  1. Ushbu satr literalni baytli massivga aylantiradi.

SpEL shuningdek, prop1.prop2.prop3 kabi standart yozuv orqali joylashgan propertylarga qo'llab-quvvatlaydi va qiymatlarni belgilashni ham amalga oshiradi. Shuningdek, ochiq maydonlarga kirish mumkin.

Keyingi misolda litteral uzunligini olish uchun nuqta orqali yozishni qanday ishlatish mumkinligini ko'rsatamiz:

Java
ExpressionParser parser = new SpelExpressionParser();
// 'getBytes().length' ga murojaat qiladi
Expression exp = parser.parseExpression("'Hello World'.bytes.length"); 
int length = (Integer) exp.getValue();
  1. 'Hello World'.bytes.length litteral uzunligini belgilaydi.
Kotlin
val parser = SpelExpressionParser()
// 'getBytes().length' ga murojaat qiladi
val exp = parser.parseExpression("'Hello World'.bytes.length") 
val length = exp.value as Int
  1. 'Hello World'.bytes.length litteral uzunligini belgilaydi.

String konstruktori satr literalidan foydalanish o'rniga chaqirilishi mumkin, quyidagi misolda ko'rsatilgan:

Java
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("new String('hello world').toUpperCase()"); 
String message = exp.getValue(String.class);
  1. Literaldan yangi String yarating va uni katta harflarga o'tkazing.
Kotlin
val parser = SpelExpressionParser()
val exp = parser.parseExpression("new String('hello world').toUpperCase()")  
val message = exp.getValue(String::class.java)
  1. Literaldan yangi String yarating va uni katta harflarga o'tkazing.

Umumiy usuldan foydalanishga e'tibor bering: public <T> T getValue(Class<T> desiredResultType). Ushbu usuldan foydalanish natija tipining kerakli natija turiga almashtirishni yo'q qiladi. Agar qiymat T turiga almashtirilmasa yoki ro'yxatga olingan tur almashtirgich bilan almashtirilmasa, EvaluationException yaratiladi.

SpELning kengroq ishlatilishi ifodani belgilanadigan obyekt (ildiz obyekt deb ataladigan) asosida baholanadigan qatorni taqdimlashdan iborat. Keyingi misolda Inventor sinfi nusxasidan name propertysi olish yoki boolean mantiqiy shart yaratish ko'rsatilmoqda:

Java
// Kalendarni yaratamiz va sozlaymiz
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);
// Konstruktorga argumentlar nomi, tug'ilgan kuni va millati.
Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name"); // Ifodani sifatida nomni tahlil qiling
String name = (String) exp.getValue(tesla);
// nom == "Nikola Tesla"
exp = parser.parseExpression("name == 'Nikola Tesla'");
boolean result = exp.getValue(tesla, Boolean.class);
// natija == true
Kotlin
// Kalendarni yaratamiz va sozlaymiz
val c = GregorianCalendar()
c.set(1856, 7, 9)
// Konstruktorga argumentlar nomi, tug'ilgan kuni va millati.
val tesla = Inventor("Nikola Tesla", c.time, "Serbian")
val parser = SpelExpressionParser()
var exp = parser.parseExpression("name") // Ifodani sifatida nomni tahlil qiling
val name = exp.getValue(tesla) as String
// nom == "Nikola Tesla"
exp = parser.parseExpression("name == 'Nikola Tesla'")
val result = exp.getValue(tesla, Boolean::class.java)
// natija == true

EvaluationContext haqida asosiy ma'lumotlar

Ifodani baholashda propertylar, metodlar yoki maydonlarni hal qilish uchun EvaluationContext interfeysi ishlatiladi, shuningdek, tur almashtirishni amalga oshirish uchun. Spring ikkita amalga oshirilishini taqdim etadi.

  • SimpleEvaluationContext: SpEL tilining asosiy funktsiyalari va konfiguratsiya variantlarining pastkuchmasini ochib beradi, bu to'liq SpEL sintaksisini talab qilmaydigan va ancha cheklangan bo'lishi kerak bo'lgan ifoda turlarini qo'llash uchun. Misollar orasida ma'lumotlarni bog'lash ifodalari va property asosida filtrlardan foydalanish kiradi.

  • StandardEvaluationContext: SpEL tilining to'liq ko'lamini ochib beradi va konfiguratsiya variantlarini ochib beradi. Siz uni standart ildiz obyektni belgilash va baholash bilan bog'liq barcha mavjud strategiyalarni sozlash uchun ishlatishingiz mumkin.

SimpleEvaluationContext faqat SpEL tilining sintaksisining qisman qo'llab-quvvatlashiga mo'ljallangan. U Java turlariga, konstruktorlariga va beanlarga havolalarni istisno qiladi. Shuningdek, u ifodalardagi propertylar va metodlarni qo'llab-quvvatlash darajasini aniq belgilashni talab qiladi. Default bo'yicha statik fabrik usuli create() faqat o'qish uchun property kirish huquqini beradi. Bitta aniq parametrga yoki quyidagi parametrlardan ba'zi kombinatsiyasiga yo'naltirilgan kerakli darajadagi qo'llab-quvvatlashni aniqlash uchun konstruktorni olish mumkin:

  • Faqat maxsus PropertyAccessor (refleksiyasiz)

  • Ma'lumotlarni bog'lash property uchun faqat o'qish

  • Ma'lumotlarni bog'lash property uchun o'qish va yozish

Tip o'zgartirish

SpEL default bo'yicha Spring yadroidagi (org.springframework.core.convert.ConversionService) mavjud mavjud tip o'zgartirish xizmatidan foydalanadi. Ushbu tip o'zgartirish xizmati umumiy konvertatsiyalarni amalga oshirish uchun ko'plab o'rnatilgan konvertorlar bilan tarqatiladi, ammo shuningdek, maxsus turlar orasidagi o'zgartirishlarni qo'shish uchun to'liq kengaytiriladi. Bundan tashqari, djenriklar bilan ham ishlay oladi. Bu shuni anglatadiki, agar siz ifodalarda typiklik bo'yicha ishlasangiz, SpEL, turlar orasidagi to'g'ri konvertatsiya qilishga intiladi.

Bu nima degani? Faraz qiling, setValue() yordamida bir List propertysiga qiymat tayinlanadi. Propertyning haqiqiy turi List<Boolean>. SpEL ro'yxatdagi elementlarni Boolean ga aylantirish kerakligini tushunadi va tegishli konvertatsiyani amalga oshiradi. Quyidagi misolda buni qanday qilish mumkinligi ko'rsatilgan:

Java
class Simple {
    public List<Boolean> booleanList = new ArrayList<Boolean>();
}
Simple simple = new Simple();
simple.booleanList.add(true);
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
// "false" bu yerda String sifatida uzatiladi. SpEL va o'zgartirish xizmati
// uning Boolean bo'lishi kerakligini tushunadi va unga mos ravishda o'zgartiradi.
parser.parseExpression("booleanList[0]").setValue(context, simple, "false");
// b - false
Boolean b = simple.booleanList.get(0);
Kotlin
class Simple {
    var booleanList: MutableList<Boolean> = ArrayList()
}
val simple = Simple()
simple.booleanList.add(true)
val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
// "false" bu yerda String sifatida uzatiladi. SpEL va o'zgartirish xizmati
// uning Boolean bo'lishi kerakligini tushunadi va unga mos ravishda o'zgartiradi.
parser.parseExpression("booleanList[0]").setValue(context, simple, "false")
// b - false
val b = simple.booleanList[0]

Parserni sozlash

SpEL ifoda parserini parser konfiguratsiyasi obyekti bilan sozlash mumkin (org.springframework.expression.spel.SpelParserConfiguration). Konfiguratsiya obyekti ifoda komponentlarining ish jarayoni logikasini boshqaradi. Masalan, agar siz massivi yoki kollektsiyani indeksatsiya qilsangiz va ko'rsatilgan indeksdagi element null bo'lsa, SpEL avtomatik ravishda ushbu elementni yaratishi mumkin. Bu odatda property havolalaridan tashkil topgan ifodalarda ma'noga ega. Agar siz massivi yoki ro'yxatni indeksatsiya qilsangiz va bir indeks ko'rsatsangiz, bu indeksga joylashtirish uchun SpEL massivi yoki ro'yxatni avtomatik ravishda kengaytirishi mumkin. Ko'rsatilgan indeksga element qo'shish uchun, SpEL element turining default konstruktoridan foydalanib, elementni yaratishga harakat qiladi, shu bilan birga ko'rsatilgan qiymatni qo'ymasdan. Agar element turi default konstruktorga ega bo'lmasa, array yoki ro'yxatga null kiritiladi. Agar qiymatni ko'rsatish uchun qandaydir ichki yoki maxsus konvertor bo'lmasa, ko'rsatilgan indeksdagi array yoki ro'yxatda null qoladi. Quyidagi misol ro'yxatni avtomatik kengaytirishni ko'rsatadi:

Java
class Demo {
    public List<String> list;
}
// Kiritamiz:
// - bo'sh (null) havolani avtomatik initsializatsiya qilish
// - avtokolleksiyaga kengaytirish
SpelParserConfiguration config = new SpelParserConfiguration(true, true);
ExpressionParser parser = new SpelExpressionParser(config);
Expression expression = parser.parseExpression("list[3]");
Demo demo = new Demo();
Object o = expression.getValue(demo);
// demo.list endi 4 yozuvdan iborat haqiqiy kollektsiya bo'ladi
// Har bir yozuv yangi bo'sh satrni ifodalaydi
Kotlin
class Demo {
    var list: List<String>? = null
}
// Kiritamiz:
// - bo'sh (null) havolani avtomatik initsializatsiya qilish
// - avtokolleksiyaga kengaytirish
val config = SpelParserConfiguration(true, true)
val parser = SpelExpressionParser(config)
val expression = parser.parseExpression("list[3]")
val demo = Demo()
val o = expression.getValue(demo)
// demo.list endi 4 yozuvdan iborat haqiqiy kollektsiya bo'ladi
// Har bir yozuv yangi bo'sh satrni ifodalaydi

SpEL da kompilyatsiya qilish

Spring Framework 4.1 asosiy ifodalarni kompilyatsiya qilishni o'z ichiga oladi. Odatda ifodalar interpretatsiya qilinadi, bu esa baholashda katta dinamik moslikni ta'minlaydi, lekin optimal ishlash natijasini bermaydi. Ifodalar orasida bevosita foydalanish uchun bu yaxshi, lekin boshqa komponentlarda, masalan, Spring Integration, ishlash muhim ahamiyat kasb etishi mumkin, lekin dinamiklikka real ehtiyoj yo'q.

SpEL kompilyatsiyasi ushbu ehtiyojni qondirish uchun mo'ljallangan. Baholash paytida kompilyator ifodaning ishlash jarayonini ifodalaydigan Java sinfini hosil qiladi va ifodalarni baholashni ancha tez amalga oshirish uchun ushbu sinfni foydalanadi. Ifodalar uchun typiklik bo'lmasa, kompilyator ifodalar interpretatsiya qilingan baholash natijasida to'plangan ma'lumotlarga asoslangan holda kompilyatsiya qiladi. Masalan, property havolasining turini faqat ifodadan bilish mumkin emas, lekin birinchi interpretatsiya qilingan baholashda u tushunishni boshlaydi. Tabiiyki, bunday hosil qilingan ma'lumotlarga asoslangan kompilyatsiya keyinchalik turli ifoda elementlarining turlari o'zgarganda ba'zi muammolarni keltirib chiqarishi mumkin. Shu sababli, kompilyatsiya tur ma'lum bo'lgan ifodalar uchun mos keladi.

Quyidagi asosiy ifodani ko'rib chiqamiz:

someArray[0].someProperty.someOtherProperty < 0.1

Oldingi ifoda arrayga kirish, propertylarni ochish va raqamli amallarni o'z ichiga olganligi sababli, ishlashdagi farq sezilarli bo'lishi mumkin. Mikro benchmarks sinovining 50000 iteratsiyasi uchun interpretatsiya qilingan baholash 75 ms vaqtni talab qildi, lekin ifodaning kompilyatsiya qilingan versiyasi atiga 3 ms vaqtni oldi.

Kompilyatorni sozlash

Kompilyator oddiy holatda yoqilmagan, ammo uni ikki turli usulda yoqish mumkin. Siz uni parser konfiguratsiyasi orqali yoki agar SpEL boshqa bir komponent ichida ishlatilayotgan bo'lsa, Spring property orqali yoqishingiz mumkin. Ushbu bo'limda ikkala variant ham ko'rib chiqiladi.

Kompilyator uch turli rejimda ishlashi mumkin, bu org.springframework.expression.spel.SpelCompilerMode enumeratorda aks ettirilgan. Rejimlar quyidagicha:

  • OFF (default): Kompilyator o'chirilgan.

  • IMMEDIATE: Darhol rejimda ifodalar imkon qadar tezroq kompilyatsiya qilinadi. Odatda, bu birinchi interpretatsiya qilingan baholashdan so'ng sodir bo'ladi. Agar kompilyatsiya qilingan ifoda ishlamasa (odatda tur o'zgarishi tufayli, avval aytib o'tilganidek), baholash usulini chaqiruvchi kod istisno oladi.

  • MIXED: Aralash rejimda ifodalar vaqt o'tishi bilan interpretatsiya qilingan va kompilyatsiya qilingan rejimlarga almashadi. Ba'zi interpretatsiya qilingan ishlaridan keyin ular kompilyatsiya qilingan shakliga o'tishadi, lekin agar kompilyatsiya qilingan shaklda biror narsa noto'g'ri ketsa (masalan, tur o'zgaradi, avval aytib o'tilganidek), ifoda avtomatik ravishda interpretatsiya qilingan shakliga qaytadi. Bir muncha vaqt o'tgach, ifoda yana boshqa kompilyatsiya qilingan shaklni yaratishi va unga o'tishi mumkin. Aslida, IMMEDIATE rejimida foydalanuvchi oladigan istisno ichki ishlov beriladi.

IMMEDIATE rejim aralash rejimda ifodalar o'zgarishi mumkin bo'lgan muammo paydo bo'lgan ifodalar uchun mavjud. Agar kompilyatsiya qilingan ifoda qisman muvaffaqiyatli ishlashidan keyin halokatli xatoga olib kelsa, ehtimol u tizim holatiga ta'sir ko'rsatgan harakatni amalga oshirgan bo'lishi mumkin. Agar bu sodir bo'lsa, chaqiruvchi kod ifodaning bir qismi ikki marta bajarilishidan saqlanishini istamasligi mumkin.

Rejimni tanlagandan so'ng, parserni SpelParserConfiguration bilan sozlash uchun foydalaning. Quyidagi misol buni qanday qilish mumkinligini ko'rsatadi:

Java
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE,
        this.getClass().getClassLoader());
SpelExpressionParser parser = new SpelExpressionParser(config);
Expression expr = parser.parseExpression("payload");
MyMessage message = new MyMessage();
Object payload = expr.getValue(message);
Kotlin
val config = SpelParserConfiguration(SpelCompilerMode.IMMEDIATE,
        this.javaClass.classLoader)
val parser = SpelExpressionParser(config)
val expr = parser.parseExpression("payload")
val message = MyMessage()
val payload = expr.getValue(message)

Agar siz kompilyator rejimini ko'rsatsangiz, siz yuklash vositasini ham ko'rsata olasiz (null uzatish mumkin). Kompilyatsiya qilingan ifodalar ko'rsatilgan klasslardan hosil bo'lgan bola yuklovchi sinfda belgilanadi. Ishonch hosil qilingki, agar yuklovchi sinf ko'rsatilgan bo'lsa, barcha turlarni baholash jarayonida ishtirok etuvchi turlarni taniy oladi. Agar yuklovchi sinfni ko'rsatmasangiz, default yuklovchi sinf ishlatiladi (odatda, baholash jarayonida ishlayotgan oqim uchun kontekst yuklovchi sinfi).

Kompilyatorni sozlashning ikkinchi usuli, agar SpEL boshqa komponentda ishlatilsa va konfiguratsiya obyekti orqali uni sozlash mumkin bo'lmasa, mo'ljallangan. Bunday hollarda spring.expression.compiler.mode property ni JVMdan tizim property sifatida (yoki SpringProperties mexanizmi orqali) birining qiymatlari bilan SpelCompilerMode(off, immediate yoki mixed) o'rnatishingiz mumkin.

Kompilyator cheklovlari

Spring Framework 4.1 dan boshlab asosiy kompilyatsiya ramkasi ishlatilmoqda. Ammo hozircha ramka barcha ifoda turlarini kompilyatsiya qilishni qo'llab-quvvatlamaydi. Dastlab asosiy e'tibor, ehtimol, ish faoliyatida muhim rol o'ynaydigan kontekstlarda ishlatilishi mumkin bo'lgan keng tarqalgan ifodalarga qaratilgan edi. Hozircha quyidagi ifoda turlari kompilyatsiya qilinmaydi:

  • Tayyor ifodalar;

  • Konversiya xizmatidan foydalanuvchi ifodalar;

  • Maxsus tanishlarda yoki kirish joylarida foydalaniladigan ifodalar;

  • Tanlov yoki proyeksiyadan foydalanadigan ifodalar.

Kelajakda ko'proq ifoda turlarini kompilyatsiya qilish mumkin bo'ladi.

Bean ta'riflarida ifodalar

BeanDefinition instance-larini aniqlash uchun XML yoki annotatsiyalarga asoslangan konfiguratsiya metama'lumotlari bilan SpEL ifodalaridan foydalanishingiz mumkin. Har ikkala holatda ham ifodani belgilash sintaksisi #{ <expression string> } ko'rinishida bo'ladi.

4.2.1. XML Konfiguratsiyasi

Property qiymati yoki konstruktor argumenti ifoda bilan belgilanadi, quyidagi misolda ko'rsatilgan:

<bean id="numberGuess" class="org.spring.samples.NumberGuess">
    <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>
    <!-- boshqa propertylar -->
</bean>

Shu bilan birga, kontekstdagi barcha beanlar odatiy bean nomi bilan oldindan belgilangan o'zgaruvchilar sifatida mavjud. Bu odatda runtime muhitiga kirish uchun environment (org.springframework.core.env.Environment) turi, shuningdek systemProperties va systemEnvironment (Map<String, Object>) kabi standart kontekst beanlarini o'z ichiga oladi.

Keyingi misolda systemProperties beaniga SpEL o'zgaruvchisi sifatida kirish ko'rsatilgan:

<bean id="taxCalculator" class="org.spring.samples.TaxCalculator">
    <property name="defaultLocale" value="#{ systemProperties['user.region'] }"/>
    <!-- boshqa propertylar -->
</bean>

Bu holatda oldindan belgilangan o'zgaruvchini # bilan oldindan belgilash shart emasligini unutmang.

Boshqa bean propertylariga nomi bilan havola qilish mumkin, quyidagi misolda ko'rsatilgan:

<bean id="numberGuess" class="org.spring.samples.NumberGuess">
    <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>
    <!-- boshqa propertylar -->
</bean>
<bean id="shapeGuess" class="org.spring.samples.ShapeGuess">
    <property name="initialShapeSeed" value="#{ numberGuess.randomNumber }"/>
    <!-- boshqa propertylar -->
</bean>

Annotatsiya konfiguratsiyasi

Standart qiymatni belgilash uchun @Value annotatsiyasini fieldlar, metodlar, metod parametrlari yoki konstruktorlarda qo'llashingiz mumkin.

Quyidagi misolda field uchun standart qiymat belgilangan:

Java
public class FieldValueTestBean {
    @Value("#{ systemProperties['user.region'] }")
    private String defaultLocale;
    public void setDefaultLocale(String defaultLocale) {
        this.defaultLocale = defaultLocale;
    }
    public String getDefaultLocale() {
        return this.defaultLocale;
    }
}
Kotlin
class FieldValueTestBean {
    @Value("#{ systemProperties['user.region'] }")
    var defaultLocale: String? = null
}

Quyidagi misolda setterning ekvivalenti ko'rsatilgan:

Java
public class PropertyValueTestBean {
    private String defaultLocale;
    @Value("#{ systemProperties['user.region'] }")
    public void setDefaultLocale(String defaultLocale) {
        this.defaultLocale = defaultLocale;
    }
    public String getDefaultLocale() {
        return this.defaultLocale;
    }
}
Kotlin
class PropertyValueTestBean {
    @Value("#{ systemProperties['user.region'] }")
    var defaultLocale: String? = null
}

Automatik aniqlangan va bog'langan metodlar va konstruktorlar ham @Value annotatsiyasidan foydalanishi mumkin, quyidagi misollarda ko'rsatilgan:

Java
public class SimpleMovieLister {
    private MovieFinder movieFinder;
    private String defaultLocale;
    @Autowired
    public void configure(MovieFinder movieFinder,
            @Value("#{ systemProperties['user.region'] }") String defaultLocale) {
        this.movieFinder = movieFinder;
        this.defaultLocale = defaultLocale;
    }
    // ...
}
Kotlin
class SimpleMovieLister {
    private lateinit var movieFinder: MovieFinder
    private lateinit var defaultLocale: String
    @Autowired
    fun configure(movieFinder: MovieFinder,
                @Value("#{ systemProperties['user.region'] }") defaultLocale: String) {
        this.movieFinder = movieFinder
        this.defaultLocale = defaultLocale
    }
    // ...
}
Java
public class MovieRecommender {
    private String defaultLocale;
    private CustomerPreferenceDao customerPreferenceDao;
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao,
            @Value("#{systemProperties['user.country']}") String defaultLocale) {
        this.customerPreferenceDao = customerPreferenceDao;
        this.defaultLocale = defaultLocale;
    }
    // ...
}
Kotlin
class MovieRecommender(private val customerPreferenceDao: CustomerPreferenceDao,
            @Value("#{systemProperties['user.country']}") private val defaultLocale: String) {
    // ...
}
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION