JavaRush /Kurslar /All lectures for UZ purposes /SpEL бўйича маълумотномали қўлланма

SpEL бўйича маълумотномали қўлланма

All lectures for UZ purposes
Daraja, Dars
Mavjud

Меъёр ифодалари

Қуйидаги меъёр ифодалари турлари қўллаб-қувватланади: қаторлар, сонлар қийматлари (int, real, hex), булевлар ва null. Қаторлар ягона қавсларда ажратилади. Қавсни қатор ичига киритиш учун икки ягона қавс белгиси ишлатинг.

Қуйидаги листингда меъёрлардан оддий фойдаланиш кўрсатилган. Оддий ҳолда улар изоляцияда эмас, балки мураккаброқ ифоданинг бир қисми сифатида ишлатилади – масалан, логик таққослаш операторининг бир томонида меъёрдан фойдаланганда.

Java
ExpressionParser parser = new SpelExpressionParser();
// "Hello World" қийматига эга
String helloWorld = (String) parser.parseExpression("'Hello World'").getValue();
double avogadrosoni = (Double) parser.parseExpression("6.0221415E+23").getValue();
// 2147483647 чиқади
int maxValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue();
boolean trueValue = (Boolean) parser.parseExpression("true").getValue();
Object nullValue = parser.parseExpression("null").getValue();
Kotlin
val parser = SpelExpressionParser()
// "Hello World" қийматига эга
val helloWorld = parser.parseExpression("'Hello World'").value as String
val avogadrosoni = parser.parseExpression("6.0221415E+23").value as Double
// 2147483647 чиқади
val maxValue = parser.parseExpression("0x7FFFFFFF").value as Int
val trueValue = parser.parseExpression("true").value as Boolean
val nullValue = parser.parseExpression("null").value

Сонларда манфий белгини, экспоненциал шаклни ва ўнлик нуқталарни ишлатиш қўллаб-қувватланади. Default ҳолда воқеий сонлар Double.parseDouble() орқали парсинг қилинади.

Хусусиятлар, массивлар, рўйхатлар, ассоциатив массивлар ва индексаторлар

Хусусиятларга шиллик қилиш ҳаволалар orqali содда. Бунинг учун нуқта ишлатинг ва қиматланган хусусиятни кўрсатинг. Inventor класи мисоллари, pupin ва tesla, маълумотлар билан тўлдирилган. Тесланинг туғилган йилни ва Пупиннинг туғилган шаҳарни олиш учун қуйидаги ифода ишлатилади:

Java
// 1856 чиқади
int year = (Integer) parser.parseExpression("birthdate.year + 1900").getValue(context);
String city = (String) parser.parseExpression("placeOfBirth.city").getValue(context);
Kotlin
// 1856 чиқади
val year = parser.parseExpression("birthdate.year + 1900").getValue(context) as Int
val city = parser.parseExpression("placeOfBirth.city").getValue(context) as String

Хусусият исмларининг биринчи ҳарфи учун регистр сезгирлигига эмас. Шундай қилиб, юқоридаги мисолдаги ифода Birthdate.Year + 1900 ва PlaceOfBirth.City сифатида ёзилиши мумкин. Бундан ташқари, хусусиятларга метод чақирувлари орқали мурожаат қилиш мумкин – масалан, getPlaceOfBirth().getCity() ўрнига placeOfBirth.city.

Массив ва рўйхат мазмунини квадрат қавслардан фойдаланиб олиш мумкин, бу қуйидаги мисолда кўрсатилган:

Java
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
// Ихтиролар массиви
// қиймати "Induction motor"
String invention = parser.parseExpression("inventions[3]").getValue(
        context, tesla, String.class);
// Аъзолар рўйхати
// қиймати "Nikola Tesla".
String name = parser.parseExpression("members[0].name").getValue(
        context, ieee, String.class);
// Аъзолар рўйхати
// қиймати "Wireless communication"
String invention = parser.parseExpression("members[0].inventions[6]").getValue(
        context, ieee, String.class);
Kotlin
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
// Ихтиролар массиви
// қиймати "Induction motor"
val invention = parser.parseExpression("inventions[3]").getValue(
        context, tesla, String::class.java)
// Аъзолар рўйхати
// қиймати "Nikola Tesla".
val name = parser.parseExpression("members[0].name").getValue(
        context, ieee, String::class.java)
// Аъзолар рўйхати
// қиймати "Wireless communication"
val invention = parser.parseExpression("members[0].inventions[6]").getValue(
        context, ieee, String::class.java)

Ассоциатив массив мазмунини олиш учун калитнинг меъёр қимати скобка ичида кўрсатилади. Қуйидаги мисолда, чунки officers ассоциатив массивининг калитлари қаторлардир, биз қатор меъёрларини кўрсатишимиз мумкин:

Java
// Офицерлар луғати
Inventor pupin = parser.parseExpression("officers['president']").getValue(
        societyContext, Inventor.class);
// қиймати "Idvor"
String city = parser.parseExpression("officers['president'].placeOfBirth.city").getValue(
        societyContext, String.class);
// қийматларни ўрнатиш
parser.parseExpression("officers['advisors'][0].placeOfBirth.country").setValue(
        societyContext, "Croatia");
Kotlin
// Офицерлар луғати
val pupin = parser.parseExpression("officers['president']").getValue(
        societyContext, Inventor::class.java)
// қиймати "Idvor"
val city = parser.parseExpression("officers['president'].placeOfBirth.city").getValue(
        societyContext, String::class.java)
// қийматларни ўрнатиш
parser.parseExpression("officers['advisors'][0].placeOfBirth.country").setValue(
        societyContext, "Croatia")

Встроенные списки

Ифодада листлаб кўрсатиш учун {} нотациясидан фойдаланиш мумкин.

Java
// Тўртта сондан иборат Java-список сифатида аниқланади
List numbers = (List) parser.parseExpression("{1,2,3,4}").getValue(context);
List listOfLists = (List) parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(context);
Kotlin
// Тўртта сондан иборат Java-список сифатида аниқланади
val numbers = parser.parseExpression("{1,2,3,4}").getValue(context) as List<*>
val listOfLists = parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(context) as List<*>

{} ўзи бўш рўйхатни англатади. Ижро самарадорлиги нуқтаи назаридан, агар рўйхат фақат собит меъёрлардан иборат бўлса, ваҳияти ҳар бир ҳисоблашда янги рўйхат қурилиши ўрнига рўйхат константалари билан ифодаланади.

Встроенные Map

Map-ларни ифодада тўғридан-тўғри {key:value} нотацияси билан ифодалаш мумкин. Қуйидаги мисолда буни қандай қилиш кўрсатилган:

Java
// Икки йўзувдан иборат Java Map сифатида аниқланади
Map inventorInfo = (Map) parser.parseExpression("{name:'Nikola',dob:'10-July-1856'}").getValue(context);
Map mapOfMaps = (Map) parser.parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}").getValue(context);
Kotlin
// Икки йўзувдан иборат Java Map сифатида аниқланади
val inventorInfo = parser.parseExpression("{name:'Nikola',dob:'10-July-1856'}").getValue(context) as Map<*, *>
val mapOfMaps = parser.parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}").getValue(context) as Map<*, *>

{:} ўзи бўш Map-ни англатади. Ижро самарадорлиги нуқтаи назаридан, агар Map ўзи собит меъёрлардан ёки константа структураларидан (рўйхатлар ёки Map-лар) иборат бўлса, ифодалашда Map константалари билан ифодаланади (аҳамиятпасари ҳар бир ҳисоблашда янги Map қурилиши ўрнига). Map калитларини қавсга олиш шарт эмас (агар калит нуқта (.) бўлмаса). Юқоридаги мисоллар қавс ишлатишмаган.

Массивлар яратиш

Java'нинг анъанавий синтаксисидан фойдаланиб массивлар яратиш мумкин, массив яратишда массивни тўлдирувчи инициализаторни кўрсатиб ўтирмай. Қуйидаги мисолда бу қандай қилинар эканлиги кўрсатилган:

Java
int[] numbers1 = (int[]) parser.parseExpression("new int[4]").getValue(context);
// Инициализаторли массив
int[] numbers2 = (int[]) parser.parseExpression("new int[]{1,2,3}").getValue(context);
// Кўп ўлчовли массив
int[][] numbers3 = (int[][]) parser.parseExpression("new int[4][5]").getValue(context);
Kotlin
val numbers1 = parser.parseExpression("new int[4]").getValue(context) as IntArray
// Инициализаторли массив
val numbers2 = parser.parseExpression("new int[]{1,2,3}").getValue(context) as IntArray
// Кўп ўлчовли массив
val numbers3 = parser.parseExpression("new int[4][5]").getValue(context) as Array<IntArray>

Кўп ўлчовли массив яратишда инициализаторни кўрсатиш ҳозирча мумкин эмас.

Методлар

Java'нинг анъанавий синтаксисидан фойдаланиб методларни чақириш мумкин. Шунингдек, меъёрлар учун ҳам методлар чақирилиши мумкин. Аргументлар учун ҳам имкониятлар қўллаб-қувватланади. Қуйидаги мисолларда методларни қандай чақириш мумкин эканлиги кўрсатилган:

Java
// қаторли меъёр, қиймати "bc"
String bc = parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class);
// true чиқади
boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(
        societyContext, Boolean.class);
Kotlin
// қаторли меъёр, қиймати "bc"
val bc = parser.parseExpression("'abc'.substring(1, 3)").getValue(String::class.java)
// true чиқади
val isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(
        societyContext, Boolean::class.java)

Операторлар

Spring Expression Language ифодалари(SpEL) қуйидаги оператор турларини қўллаб-қувватлайди:

  • Реляцион операторлар

  • Логик операторлар

  • Математик операторлар

  • Масалани бириктириш оператори

Реляцион операторлар

Реляцион операторлар (тўғри (equal), нотўғри (not equal), кичик (less than), кичик ёки тенг (less than or equal), катта (greater than) ва катта ёки тенг (greater than or equal) стандарт оператор белгиларидан фойдаланилиб қўллаб-қувватланади. Қуйидаги листингда бир нечта операторлар мисоллари келтирилган:

Java
// true чиқади
boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class);
// false чиқади
boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class);
// true чиқади
boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);
Kotlin
// true чиқади
val trueValue = parser.parseExpression("2 == 2").getValue(Boolean::class.java)
// false чиқади
val falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean::class.java)
// true чиқади
val trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean::class.java)

Кичик ва катта ҳарфларга нисбатан таққослаш null учун оддий қоидага бўлган бўйсунади: null ҳеч нарса сифатида ҳисобланади (бу 0 эмас). Шунга кўра, ҳар қандай бошқа қиммат null(X > null) ҳар доим true бўлади ва ҳеч қандай бошқа қиммат ҳеч қачон null(X < null) бўлмайди ва ҳар доим false бўлади).

Числовий таққослашларни афзал кўрсангиз, null таянчидан кўра таянч таққослашдан фойдаланиб таққослашларни амалга оширасиз (массалан, X > 0 ёки X < 0).

Стандарт реляцион операторларга қўшимча тарзида SpEL instanceof ва регекс асосида matches операторларини қўллаб-қувватлайди. Қуйидаги мисолларда иккаласи ҳам келтирилган:

Java
// false чиқади
boolean falseValue = parser.parseExpression(
        "'xyz' instanceof T(Integer)").getValue(Boolean.class);
// true чиқади
boolean trueValue = parser.parseExpression(
        "'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
// false чиқади
boolean falseValue = parser.parseExpression(
        "'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
Kotlin
// false чиқади
val falseValue = parser.parseExpression(
        "'xyz' instanceof T(Integer)").getValue(Boolean::class.java)
// true chiqadi
val trueValue = parser.parseExpression(
        "'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
// false chiqadi
val falseValue = parser.parseExpression(
        "'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
Примитив турларига нисбатан эҳтиёт бўлиш лозим, чунки улар дарҳол ўзларининг қопланган турларига ўрама қилинади. Масалан, 1 instanceof T(int) бемиз ҳақиқат, ва 1 instanceof T(Integer) мана кутилганидек ҳақиқат.

Ҳар бир символли операторнинг текстли эквиваленти ҳам бор. Бундай қилиш орқали ифодани киритишда ишлатиладиган символлар типи учун ташвиш узоқлаштирилади (масалан, XML ҳужжатда). Текст эквивалентлари:

  • lt (<)

  • gt (>)

  • le (<=)

  • ge (>=)

  • eq (==)

  • ne (!=)

  • div (/)

  • mod (%)

  • not (!).

Ҳар бир текстли операторлар қийматсизликга сезгир эмас.

Логик операторлар

SpEL қуйидаги логик операторларни қўллаб-қувватлайди:

  • and (&&)

  • or (||)

  • not (!)

Қуйидаги мисолда логик операторлардан фойдаланиш кўрсатилган:

Java
// -- AND --
// false chiqadi
boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class);
// true chiqadi
String expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')";
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
// -- OR --
// true chiqadi
boolean trueValue = parser.parseExpression("true or false").getValue(Boolean.class);
// true chiqadi
String expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')";
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
// -- NOT --
// false chiqadi
boolean falseValue = parser.parseExpression("!true").getValue(Boolean.class);
// -- AND and NOT --
String expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')";
boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
Kotlin
// -- AND --
// false chiqadi
val falseValue = parser.parseExpression("true and false").getValue(Boolean::class.java)
// true chiqadi
val expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')"
val trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)
// -- OR --
// true chiqadi
val trueValue = parser.parseExpression("true or false").getValue(Boolean::class.java)
// true chiqadi
val expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')"
val trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)
// -- NOT --
// false chiqadi
val falseValue = parser.parseExpression("!true").getValue(Boolean::class.java)
// -- AND and NOT --
val expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')"
val falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean::class.java)

Математик операторлар

Қўшиш операторы (+) ҳам сонлар учун, ҳам қаторлар учун ишлатилиши мумкин. Айириш (-), кўпайтириш (*) ва бўлиш (/) операторлари фақат сонлар учун ишлатилиши мумкин. Шунингдек, қолдиқни олиш (%) ва экспоненциал ўсиш (^) операторлари сонларга ишлатилиши мумкин. Стандарт оператор устунлиги қўлланилади. Қуйидаги мисолларда математик операторлардан фойдаланиш кўрсатилган:

Java
// Қўшиш
int two = parser.parseExpression("1 + 1").getValue(Integer.class);  // 2
String testString = parser.parseExpression(
        "'test' + ' ' + 'string'").getValue(String.class);  // 'test string'
// Айириш
int four = parser.parseExpression("1 - -3").getValue(Integer.class);  // 4
double d = parser.parseExpression("1000.00 - 1e4").getValue(Double.class);  // -9000
// Кўпайтириш
int six = parser.parseExpression("-2 * -3").getValue(Integer.class);  // 6
double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class);  // 24.0
// Бўлиш
int minusTwo = parser.parseExpression("6 / -3").getValue(Integer.class);  // -2
double one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double.class);  // 1.0
// Қолдиқни олиш
int three = parser.parseExpression("7 % 4").getValue(Integer.class);  // 3
int one = parser.parseExpression("8 / 5 % 2").getValue(Integer.class);  // 1
// Оператор устунлиги
int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Integer.class);  // -21
Kotlin
// Қўшиш
val two = parser.parseExpression("1 + 1").getValue(Int::class.java)  // 2
val testString = parser.parseExpression(
        "'test' + ' ' + 'string'").getValue(String::class.java)  // 'test string'
// Айириш
val four = parser.parseExpression("1 - -3").getValue(Int::class.java)  // 4
val d = parser.parseExpression("1000.00 - 1e4").getValue(Double::class.java)  // -9000
// Кўпайтириш
val six = parser.parseExpression("-2 * -3").getValue(Int::class.java)  // 6
val twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double::class.java)  // 24.0
// Бўлиш
val minusTwo = parser.parseExpression("6 / -3").getValue(Int::class.java)  // -2
val one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double::class.java)  // 1.0
// Қолдиқни олиш
val three = parser.parseExpression("7 % 4").getValue(Int::class.java)  // 3
val one = parser.parseExpression("8 / 5 % 2").getValue(Int::class.java)  // 1
// Оператор устунлиги
val minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Int::class.java)  // -21

Бириктириш оператори

Хусусиятни белгиловчи учун бириктириш оператори (=) ни ишлатинг. Бу одатда setValue чақируви ичида амалга оширилади, лекин getValue чақируви ичида ҳам амалга оширилиши мумкин. Қуйидаги листингда бириктириш оператори ичида ишлатишнинг иккала тартиби кўрсатилган:

Java
Inventor inventor = new Inventor();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
parser.parseExpression("name").setValue(context, inventor, "Aleksandar Seovic");
// алтернатива
String aleks = parser.parseExpression(
        "name = 'Aleksandar Seovic'").getValue(context, inventor, String.class);
Kotlin
val inventor = Inventor()
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
parser.parseExpression("name").setValue(context, inventor, "Aleksandar Seovic")
// алтернатива
val aleks = parser.parseExpression(
        "name = 'Aleksandar Seovic'").getValue(context, inventor, String::class.java)

Турлар

Сиз java.lang.Class (тип) инстанциясини аниқлаш учун махсус T операторини ишлатишингиз мумкин. Статик методлар ҳам ушбу оператор орқали чақирилади. StandardEvaluationContext турларни топиш учун TypeLocator дан фойдаланади, ва StandardTypeLocator (кўрсатилиши мумкин) java.lang пакетининг хусусиятларини эътиборга олган ҳолда қурилади. Бу java.lang пакетидан бефароқ T() дан фойдаланиш учун, лекин бошқа ҳар қандай тур учун тўлиқ аниқлаш кераклигини англатади. Қуйидаги мисолда T операторини қандай ишлатиш мумкинлилиги кўрсатилган:

Java
Class dateClass = parser.parseExpression("T(java.util.Date)").getValue(Class.class);
Class stringClass = parser.parseExpression("T(String)").getValue(Class.class);
boolean trueValue = parser.parseExpression(
        "T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR")
        .getValue(Boolean.class);
Kotlin
val dateClass = parser.parseExpression("T(java.util.Date)").getValue(Class::class.java)
val stringClass = parser.parseExpression("T(String)").getValue(Class::class.java)
val trueValue = parser.parseExpression(
        "T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR")
        .getValue(Boolean::class.java)

Конструкторлар

Конструкторларни new оператори орқали чақириш мумкин. java.lang(Integer, Float, String ва ҳ.к.) пакетлари ичидаги турлардан ташқари бошқа турлар учун тўлиқ аниқлашни ишлатиш керак. Қуйидаги мисолда new операторини конструкторларни чақириш учун ишлатиш қандай қилинади:

Java
Inventor einstein = p.parseExpression(
        "new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German')")
        .getValue(Inventor.class);
// Inventor'нинг янги экземплярини add() List методида яратишимиз
p.parseExpression(
        "Members.add(new org.spring.samples.spel.inventor.Inventor(
            'Albert Einstein', 'German'))").getValue(societyContext);
Kotlin
val einstein = p.parseExpression(
        "new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German')")
        .getValue(Inventor::class.java)
// Inventor'нинг янги экземплярини add() List методида яратишимиз
p.parseExpression(
        "Members.add(new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German'))")
        .getValue(societyContext)

Ўзгарувчилар

Ифодада ўзгарувчиларга мурожаат қилиш учун #variableName синтаксисидан фойдаланиш мумкин. Ўзгарувчилар EvaluationContext амалга оширилишида setVariable методи орқали белгиланади.

Илгари маълумотлар тўғри ўзгарувчи номларини ташкил этувчи бир ёки бир неча белгилардан иборат бўлиши керак.

  • ҳарфлар: A дан Z ва a дан z гача

  • рақамлар: 0 дан 9 гача

  • изнинг узун чизиғи: _

  • доллар белги: $

Қуйидаги мисолда, ўзгарувчилардан қандай фойдаланиш мумкинлиги кўрсатилган.

Java
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
context.setVariable("newName", "Mike Tesla");
parser.parseExpression("name = #newName").getValue(context, tesla);
System.out.println(tesla.getName())  // "Mike Tesla"
Kotlin
val tesla = Inventor("Nikola Tesla", "Serbian")
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
context.setVariable("newName", "Mike Tesla")
parser.parseExpression("name = #newName").getValue(context, tesla)
println(tesla.name)  // "Mike Tesla"

Ўзгарувчилар #this ва #root

#this ўзгарувчиси ҳар доим олдин белгиланади ва ҳозирги ҳисоблов объектига мурожаат қилади (ноқулай мурожаатлар нисбатан). #root ўзгарувчиси ҳар доим олдин белгиланади ва контекстни тагига мурожаат қилади. Ифода элементлари ҳисобланиши билан #this ўзгарувчиси ўзгариши мумкин, #root ўзгарувчиси ҳар доим тагинианглаб туриб мурожаат қилади. Қуйидаги мисолларда #this ва #root ўзгарувчиларидан қандай фойдаланиш мумкинлиги кўрсатилган:

Java
// бутун сонлар массивини яратамиз
List<Integer> primes = new ArrayList<Integer>();
primes.addAll(Arrays.asList(2,3,5,7,11,13,17));
// таҳлил қилувчисини яратамиз ва "primes" ўзгарувчисини бутун сонлар массиви сифатида белгиламиз
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataAccess();
context.setVariable("primes", primes);
// барча 10 дан катта бўлган простие сонлар рўйхатидан (tanlov ?{...})
// мисолида [11, 13, 17] чиқади
List<Integer> primesGreaterThanTen = (List<Integer>) parser.parseExpression(
        "#primes.?[#this>10]").getValue(context);
Kotlin
// бутун сонлар массивини яратамиз
val primes = ArrayList<Int>()
primes.addAll(listOf(2, 3, 5, 7, 11, 13, 17))
// таҳлил қилувчисини яратамиз ва "primes" ўзгарувчисини бутун сонлар массиви сифатида белгиламиз
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadOnlyDataAccess()
context.setVariable("primes", primes)
// барча 10 дан катта бўлган простие сонлар рўйхатидан (tanlov ?{...})
// мисолида [11, 13, 17] чиқади
val primesGreaterThanTen = parser.parseExpression(
        "#primes.?[#this>10]").getValue(context) as List<Int>

Функциялар

SpEL ни кенгайтириш имконияти мавжуд, ҳар қандай фойдаланувчи функцияни рўйхатдан ўтказиш мумкин, уларни ифоданинг қатор орасида чақира олалар. Функция EvaluationContext орқали рўйхатдан ўтилади. Қуйидаги мисолда қандай қилиб фойдаланувчи функцияни рўйхатдан ўтказиш мумкинлиги кўрсатилган:

Java
Method method = ...;
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
context.setVariable("myFunction", method);
Kotlin
val method: Method = ...
val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
context.setVariable("myFunction", method)

Масалан, бир қатори инверсия қиладиган қуйидаги ёрдамчи методни кўриб чиқинг:

Java
public abstract class StringUtils {
    public static String reverseString(String input) {
        StringBuilder backwards = new StringBuilder(input.length());
        for (int i = 0; i < input.length(); i++) {
            backwards.append(input.charAt(input.length() - 1 - i));
        }
        return backwards.toString();
    }
}
Kotlin
fun reverseString(input: String): String {
    val backwards = StringBuilder(input.length)
    for (i in 0 until input.length) {
        backwards.append(input[input.length - 1 - i])
    }
    return backwards.toString()
}

Анъанавий методни рўйхатдан ўтказиб, қуйидаги мисолда кўрсатилган ҳолатда ишлатилиши мумкин:

Java
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
context.setVariable("reverseString",
        StringUtils.class.getDeclaredMethod("reverseString", String.class));
String helloWorldReversed = parser.parseExpression(
        "#reverseString('hello')").getValue(context, String.class);
Kotlin
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
context.setVariable("reverseString", ::reverseString::javaMethod)
val helloWorldReversed = parser.parseExpression(
        "#reverseString('hello')").getValue(context, String::class.java)

Binlarga мурожаат

Aгар ҳисоблов контексти binлар розоватидан фойдаланадиган бўлса, @ белгиси билан ифодада binларни кўришингиз мумкин. Қуйидаги мисолда бу амалга оширилади:

Java
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new MyBeanResolver());
// Бу MyBeanResolver учун resolve(context, "something")'ни ҳисоблаш пайтида чақиришни юзатади
Object bean = parser.parseExpression("@something").getValue(context);
Kotlin
val parser = SpelExpressionParser()
val context = StandardEvaluationContext()
context.setBeanResolver(MyBeanResolver())
// Бу MyBeanResolver учун resolve(context, "something")'ни ҳисоблаш пайтида чақиради
val bean = parser.parseExpression("@something").getValue(context)

Bin-fabrикани ўзини кўриш учун bin'нинг номи ўрнига & белгисини қўйиш лозим. Қуйидаги мисолда бу қилинади:

Java
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new MyBeanResolver());
// Бу MyBeanResolver учун resolve(context,"&foo")'ни ҳисоблаш пайтида чақиради
Object bean = parser.parseExpression("&foo").getValue(context);
Kotlin
val parser = SpelExpressionParser()
val context = StandardEvaluationContext()
context.setBeanResolver(MyBeanResolver())
// Бу MyBeanResolver учун resolve(context,"&foo")'ни ҳисоблаш пайтида чақиради
val bean = parser.parseExpression("&foo").getValue(context)

Ternarniy operator (If-Then-Else)

Ternarniy оператордан if-then-else (агар-то-бошқа) шартли ўтиш логикасида ифода ичида фойдаланиш мумкин. Қуйидаги листингда оддий мисол келтирилган:

Java
String falseString = parser.parseExpression(
        "false ? 'trueExp' : 'falseExp'").getValue(String.class);
Kotlin
val falseString = parser.parseExpression(
        "false ? 'trueExp' : 'falseExp'").getValue(String::class.java)

Бу ёки бугунги хузурли false бўлгани учун натижада 'falseExp' қатор қиймати келади. Келгуси мисол яқинроқ амалиётга:

Java
parser.parseExpression("name").setValue(societyContext, "IEEE");
societyContext.setVariable("queryName", "Nikola Tesla");
expression = "isMember(#queryName)? #queryName + ' is a member of the ' " +
        "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'";
String queryResultString = parser.parseExpression(expression)
        .getValue(societyContext, String.class);
// queryResultString = "Nikola Tesla is a member of the IEEE Society"
Kotlin
parser.parseExpression("name").setValue(societyContext, "IEEE")
societyContext.setVariable("queryName", "Nikola Tesla")
expression = "isMember(#queryName)? #queryName + ' is a member of the ' " + "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'"
val queryResultString = parser.parseExpression(expression)
        .getValue(societyContext, String::class.java)
// queryResultString = "Nikola Tesla is a member of the IEEE Society"

Келгуси қисмда Элвис оператори ҳақидаги қисқа синтаксис учун қаранг.

Элвис оператори

Элвис оператори (Elvis operator) – тернарни операторнинг қисқартилган синтаксиси ва Groovy тилидан келиб чиққан. Тернарни оператор синтаксисини фойдаланишда кўпинча ўзгарувчини икки марта такрорлашга сабаб бўлади, қуйидаги мисолдаги каби:

String name = "Elvis Presley";
String displayName = (name != null ? name : "Unknown");

Бу билан сиз Элвис операторини (Элвис Преслининг сочи услубига ўхшаб) ишлатишингиз мумкин. Қуйидаги мисолда Элвис оператори қандай ишлатилиши кўрсатилган:

Java
ExpressionParser parser = new SpelExpressionParser();
String name = parser.parseExpression("name?:'Unknown'").getValue(new Inventor(), String.class);
System.out.println(name);  // 'Unknown'
Kotlin
val parser = SpelExpressionParser()
val name = parser.parseExpression("name?:'Unknown'").getValue(Inventor(), String::class.java)
println(name)  // 'Unknown'

Қуйидаги листингда кўпроқ мураккаб мисол келтирилган:

Java
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
String name = parser.parseExpression("name?:'Elvis Presley'").getValue(context, tesla, String.class);
System.out.println(name);  // Nikola Tesla
tesla.setName(null);
name = parser.parseExpression("name?:'Elvis Presley'").getValue(context, tesla, String.class);
System.out.println(name);  // Elvis Presley
Kotlin
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
val tesla = Inventor("Nikola Tesla", "Serbian")
var name = parser.parseExpression("name?:'Elvis Presley'").getValue(context, tesla, String::class.java)
println(name)  // Nikola Tesla
tesla.setName(null)
name = parser.parseExpression("name?:'Elvis Presley'").getValue(context, tesla, String::class.java)
println(name)  // Elvis Presley

Сиз Элвис операторидан ифодаларда default қийматларни қўллаш учун фойдаланишингиз мумкин. Қуйидаги мисол @Value билан аннотацияланган ифодада Элвис операторидан қандай фойдаланиш мумкинлигини кўрсатади:

@Value("#{systemProperties['pop3.port'] ?: 25}")

Бу pop3.port систем таъминотини, агар у аниқланган бўлса, ёки 25 бўлмаса аниқлайди.

Хавфсиз навигация оператори

Хавфсиз навигация оператори NullPointerException ни олдимоқликни олдиради ва Groovy тилидан келиб чиқади. Одатда, агар бир объектга мурожаат бўлса, объект методлари ёки хусусиятларига мурожаат қилишдан аввал унинг бошқалардан бўш эмаслигини текшириш керак бўлиши мумкин. Буни олдимоқлик учун, хавфсиз навигация оператори null қайтариш ўрнига исключенме тўғилдирмайди. Қуйидаги мисолда хавфсиз навигация операторини қандай ишлатиш мумкинлиги кўрсатилган:

Java
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
tesla.setPlaceOfBirth(new PlaceOfBirth("Smiljan"));
String city = parser.parseExpression("placeOfBirth?.city").getValue(context, tesla, String.class);
System.out.println(city);  // Smiljan
tesla.setPlaceOfBirth(null);
city = parser.parseExpression("placeOfBirth?.city").getValue(context, tesla, String.class);
System.out.println(city);  // null - ҳеч қандай NullPointerException келтирмайди!!!
Kotlin
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadOnlyDataBinding().build()
val tesla = Inventor("Nikola Tesla", "Serbian")
tesla.setPlaceOfBirth(PlaceOfBirth("Smiljan"))
var city = parser.parseExpression("placeOfBirth?.city").getValue(context, tesla, String::class.java)
println(city)  // Smiljan
tesla.setPlaceOfBirth(null)
city = parser.parseExpression("placeOfBirth?.city").getValue(context, tesla, String::class.java)
println(city)  // null - ҳеч қандай NullPointerException келтирмайди!!!
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION