Как настроить парсер SpEL в Spring?

SpEL — отличная функция, предоставляемая Spring, но иногда использование SpEL для вызова конструкторов класса немного утомительно, это пример.

<bean id="plainPojo" class="myPackage.PoJo">
    <property name="date" value="#{new java.util.Date()}"/>
</bean>

Чтобы инициировать экземпляр Date, я должен включить полное имя класса Date. Есть ли способ, которым я могу определить настраиваемый синтаксический анализатор SpEL, чтобы мне не приходилось писать полное имя класса, который я хочу использовать?

Кстати, на SpEL можно писать так:

<bean id="plainPojo" class="myPackage.PoJo">
    <property name="name" value="#{new String('myName')}"/>
</bean>

Класс String находится в пакете java.lang, поэтому я думаю, что синтаксический анализатор SpEL по умолчанию, используемый инфраструктурой Spring, уже включает путь java.lang.


person Jade Tang    schedule 23.09.2014    source источник
comment
Синтаксический анализатор SpEL следует соглашениям Java по умолчанию, и в них говорится, что все в пакете java.lang доступно (вы не увидите пакеты java.lang в операторе импорта). Кроме того, почему вы хотите программировать в XML, в этом случае это не кажется действительно полезным, поскольку вместо этого вы, вероятно, захотите поместить это в обычный код Java.   -  person M. Deinum    schedule 23.09.2014
comment
это всего лишь пример, я хочу вызвать какую-то пользовательскую функцию при запуске bean-компонента. Возможно, это то, что я ищу docs.spring.io/spring-integration /reference/html/spel.html   -  person Jade Tang    schedule 23.09.2014
comment
Смотрите мой ответ ниже.   -  person Gary Russell    schedule 23.09.2014


Ответы (2)


При программном использовании SpEL вы можете внедрить StandardTypeLocator в контекст оценки после добавления ваших пакетов в StandardTypeLocator с помощью registerImport(). (Так вы бы сделали это при использовании SpEL в потоках Spring Integration). Это делает его более удобным при использовании пользовательских классов в выражениях SpEL.

Мы используем эту технику в конечные точки Twitter.

То же самое при использовании пользовательских функций — они должны быть зарегистрированы в контексте оценки.

Вы можете настроить контекст оценки, используемый при подключении bean-компонентов (#{...}), внедрив пользовательский BeanExpressionResolver в фабрику bean-компонентов контекста приложения. Подкласс StandardBeanExpressionResolver и переопределение customizeEvaluationContext() перед refresh() контекстом.

person Gary Russell    schedule 23.09.2014

Чтобы дополнить ответ Гэри:

Вы можете настроить контекст оценки, используемый при связывании bean-компонентов (#{...}), внедрив пользовательский BeanExpressionResolver в фабрику bean-компонентов контекста приложения. Подкласс StandardBeanExpressionResolver и переопределение customEvaluationContext() перед обновлением() контекста.

Этого можно добиться, написав BeanFactoryPostProcessor, как показано ниже:

public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
       beanFactory.setBeanExpressionResolver(new CustomBeanExpressionResolver());
   }
}

BeanFactoryPostProcessor будет автоматически выбран Spring, если вы зарегистрируете его как bean-компонент.

person Mircea D.    schedule 29.04.2015