Главная » Spring » Основы языка выражений SpEL Spring

0

Конечная цель выражений на языке SpEL состоит в том, чтобы обеспечить возможность вычисления некоторых значений. В про- цессе вычислений могут участвовать другие значения. Самой прос- той разновидностью значений в языке SpEL являются литералы, ссылки на свойства компонентов и константы в некоторых классах.

Литералы

Простейшим выражением на языке SpEL является выражение, состоящее из одного литерального значения. Например, ниже при- водится вполне допустимое выражение на языке SpEL:

5

Неудивительно, что результатом этого выражения является це- лое число 5. Это значение можно было бы внедрить в свойство компонента с помощью конструкции #{} в атрибуте value элемента

<property>, как показано ниже:

<property name="count" value="#{5}"/>

Конструкция #{} подсказывает фреймворку Spring, что ее содер- жимое является выражением на языке SpEL. Эти выражения можно также смешивать с обычными значениями:

<property name="message" value="The value is #{5}"/>

На языке SpEL можно также определять вещественные числа. Например:

<property name="frequency" value="#{89.7}"/>

Числа могут записываться в научной форме записи. Как показа- но в следующем фрагменте, который присваивает значение 10000.0 свойству  capacity:

<property  name="capacity"  value="#{1e4}"/>

Язык SpEL также поддерживает строковые литералы, которые могут заключаться в апострофы или кавычки. Например, внедре- ние строкового литерала в свойство компонента можно записать так:

<property   name="name"   value="#{‘Chuck’}"/>

Если для определения значений XML-атрибутов используются апострофы, выражение на языке SpEL можно заключить в кавычки:

<property  name=’name’  value=’#{"Chuck"}’/>

Для определения логических значений можно использовать пару литералов true и false. Например, значение false можно выразить так:

<property  name="enabled"  value="#{false}"/>

Работа с литералами в выражениях на языке SpEL является обыденным делом. Однако, чтобы присвоить целочисленному свойству значение 5 или логическому свойству значение false, совсем необязательно использовать выражения на языке SpEL. Я считаю, что нет смысла использовать выражения на языке SpEL, содержащие только литералы. Но напомню, что даже самые за- мысловатые выражения состоят из более простых подвыражений. Поэтому знание приемов работы с литералами не будет лишним. Рано или поздно, с ростом сложности выражений, они все равно потребуются.

Ссылки на компоненты и обращение к их свойствам и методам

Другой основной особенностью выражений на языке SpEL явля- ется возможность ссылаться на другие компоненты по их иденти- фикаторам. Например, с помощью выражения на языке SpEL можно внедрить компонент в свойство другого компонента:

<property name="instrument" value="#{saxophone}"/>

Здесь для внедрения компонента с идентификатором "saxophone" в свойство instrument было использовано выражение SpEL. Но по- стойте… разве нельзя сделать то же самое без выражения SpEL, вос- пользовавшись атрибутом ref, как показано ниже?

<property  name="instrument"  ref="saxophone"/>

Да, результат будет тем же самым. И да, для этого не нужно ис- пользовать выражение на языке SpEL. Но весь интерес в том, что это возможно, и чуть ниже я покажу, в каких ситуациях может при- годиться возможность внедрения ссылок на компоненты с помощью выражений. А сейчас я хочу показать, как пользоваться ссылками на компоненты для доступа к их свойствам в выражениях.

Допустим, что необходимо настроить новый компонент Instru- mentalist с идентификатором carl. Карл – необычный музыкант, он – подражатель. Вместо собственного музыкального произведения Карл будет исполнять то же произведение, что исполняет Кенни. При конфигурировании компонента carl можно воспользоваться выражением на языке SpEL, чтобы скопировать произведение из свойства song   Кенни, как показано ниже:

<bean id="carl"

class="com.springinaction.springidol.Instrumentalist">

<property name="song" value="#{kenny.song}" />

</bean>

Как показано на рис. 2.1, выражение, внедряющее значение в свойство song, состоит из двух частей.

Первая часть (перед точкой) ссылается на компонент kenny по его идентификатору. Вторая часть ссылается на свойство song компонен- та kenny. Подобное внедрение значения в свойство song компонента carl фактически равносильно операции присваивания, выполненной программно, как показано ниже:

Instrumentalist   carl   =   new   Instrumentalist(); carl.setSong(kenny.getSong());

Да! Наконец-то мы нашли более интересное применение выраже- ниям на языке SpEL. Это очень простое выражение, но я не вижу более простого способа реализовать то же самое без SpEL.

И это еще не все! Мы только начинаем.

Рис. 2.1. Обращение

к свойству другого компонента

с использованием языка выражений Spring

Возможность обращения к свойствам – не единственное, что можно делать с компонентами. Точно так же можно вызывать ме- тоды компонентов. Например, представьте, что имеется компонент songSelector с методом selectSong(), возвращающим музыкальное про- изведение для исполнения. В этом случае Карл мог бы исполнять произведения, предлагаемые компонентом songSelector:

<property   name="song"   value="#{songSelector.selectSong()}"/>

Теперь предположим, что по некоторой причине Карл пожелал, чтобы название произведения передавалось ему в виде строки, со-

стоящей только из заглавных символов. Нет проблем… для этого достаточно вызвать метод toUpperCase() строкового значения:

<property   name="song"   value="#{songSelector.selectSong().toUpperCase()}"/>

Этот трюк будет срабатывать всегда… пока метод selectSong() не вернет значение null. Если в какой-то момент selectSong() вер- нет null, во время вычисления выражения возникнет исключение NullPointerException.

Чтобы избежать появления жуткого исключения NullPointer- Exception в выражении, следует задействовать защищенный оператор доступа к свойству:

<property   name="song"   value="#{songSelector.selectSong()?.toUpperCase()}"/>

Здесь вместо одиночной точки (.) для вызова метода toUpperCase() используется оператор ?.. Этот оператор сначала проверяет, не яв- ляется ли пустым элемент слева, и только потом выполняет обра- щение к элементу справа. То есть если selectSong() вернет значение null, тогда выражение не будет даже пытаться вызвать toUpperCase().

Создание выражений, манипулирующих другими компонента- ми, – отличное начало. Но что, если потребуется вызвать статиче- ский метод класса или получить значение константы? Для этого необходимо познакомиться с особенностями использования типов в языке SpEL.

Использование типов

Ключом к использованию методов класса и констант в языке SpEL является оператор T(). Например, чтобы обратиться к Java- классу Math в выражении на языке SpEL, необходимо использовать оператор T(), как показано ниже:

T(java.lang.Math)

Результатом оператора T(), представленного здесь, является объ- ект типа Class, представляющий класс java.lang.Math. Этот результат можно было бы даже внедрить в свойство компонента типа Class. Но истинная ценность значения, возвращаемого оператором T(), заклю- чается в возможности доступа к статическим методам и константам указанного класса.

Например, предположим, что в свойство компонента необходимо внедрить значение pi. В этом случае достаточно просто обратиться к константе PI в классе Math, как показано ниже:

<property name="multiplier" value="#{T(java.lang.Math).PI}"/>

Аналогично с помощью оператора T() можно вызывать статиче- ские методы. Например, ниже показано, как в свойство компонента внедрить случайное число (в диапазоне от 0 до 1):

<property name="randomNumber" value="#{T(java.lang.Math).random()}"/>

В момент запуска приложения, когда дело дойдет до инициали- зации свойства randomNumber, фреймворк Spring вызовет метод Math. random() и присвоит полученное значение этому свойству. Это еще один пример операций, которые трудно было бы реализовать без применения выражений на языке SpEL.

Теперь, когда мы добавили в наш арсенал несколько основных приемов использования выражений на языке SpEL, сделаем еще шаг и познакомимся с операциями, которые можно выполнять с этими простыми выражениями.

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии