Программно оценить выражение bean-компонента с помощью Spring Expression Language

У меня есть простое выражение Spring Bean Expression, которое отлично оценивается, когда я определяю его внутри файла контекста приложения:

<bean id="myConfigBean" class="com.example.myBeanConfigBean">
    <property name="myProperty" value="#{ someOtherBean.getData() }"/>
</bean>

Теперь я хочу сделать ту же оценку программно. Я использовал следующий код:

final ExpressionParser parser = new SpelExpressionParser();
final TemplateParserContext templateContext = new TemplateParserContext();
Expression expression = parser.parseExpression("#{ someOtherBean.getData() }", templateContext);
final String value = (String) expression.getValue();

Это вызывает исключение:

EL1007E:(pos 22): Field or property 'someOtherBean' cannot be found on null

Я думаю, мне нужно как-то установить корневой объект, который позволяет настроить bean-компоненты как свойство. Но я еще не заставил его работать. Кто уже делал это и может подсказать?


person Jack    schedule 23.07.2012    source источник


Ответы (2)


реализовать BeanFactoryAware, чтобы получить ссылку на фабрику компонентов; потом...

StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new BeanFactoryResolver(this.beanFactory));
Expression expression = parser.parseExpression("@someOtherBean.getData()"); 
// or "@someOtherBean.data"
final String value = expression.getValue(context, String.class);

ИЗМЕНИТЬ

Чтобы ответить на комментарий ниже. @ инициирует использование преобразователя фабрики компонентов для доступа к компоненту; альтернативой является добавление BeanExpressionContextAccessor в контекст оценки и использование BeanExpressionContext в качестве корневого объекта для оценки...

final ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new BeanFactoryResolver(beanFactory));
context.addPropertyAccessor(new BeanExpressionContextAccessor());
Expression expression = parser.parseExpression("someOtherBean.getData()");
BeanExpressionContext rootObject = new BeanExpressionContext(beanFactory, null);

...

String value = expression.getValue(context, rootObject, String.class);
person Gary Russell    schedule 23.07.2012
comment
Могу ли я использовать приведенное выше выражение без символа «@»? @someOtherBean.getData() ›› someOtherBean.getData(). - person RiyasAbdulla; 23.04.2017
comment
Не без дополнительной настройки; см. редактирование моего ответа. Вы действительно должны задать новый вопрос - администраторы здесь не любят новые вопросы в комментариях. - person Gary Russell; 23.04.2017
comment
@Gary Russell У меня аналогичное требование, разница только в том, что мой метод принимает параметры. Как передать динамические параметры? Итак, сигнатура метода - someOtherBean.getData(Objec[] args), я ищу способ передать параметры. Пробовал использовать выражение Expression = parser.parseExpression(someOtherBean.getData(#args)) но у меня не работает - person JDev; 20.02.2020
comment
Не задавайте новые вопросы в комментариях к старым ответам. Этому почти 8 лет!!! Задайте новый вопрос и предоставьте гораздо больше контекста. Откуда вы ожидаете получить значение #args? Само выражение может оценить значение, которое будет передано в метод. - person Gary Russell; 20.02.2020

Пожалуйста, посмотрите @ https://www.mkyong.com/spring3/test-spring-el-with-expressionparser/

Пример Java-кода

import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

public class App {
    public static void main(String[] args) {

        ExpressionParser parser = new SpelExpressionParser();

        //literal expressions
        Expression exp = parser.parseExpression("'Hello World'");
        String msg1 = exp.getValue(String.class);
        System.out.println(msg1);

        //method invocation
        Expression exp2 = parser.parseExpression("'Hello World'.length()");
        int msg2 = (Integer) exp2.getValue();
        System.out.println(msg2);

        //Mathematical operators
        Expression exp3 = parser.parseExpression("100 * 2");
        int msg3 = (Integer) exp3.getValue();
        System.out.println(msg3);

        //create an item object
        Item item = new Item("mkyong", 100);
        //test EL with item object
        StandardEvaluationContext itemContext = new StandardEvaluationContext(item);

        //display the value of item.name property
        Expression exp4 = parser.parseExpression("name");
        String msg4 = exp4.getValue(itemContext, String.class);
        System.out.println(msg4);

        //test if item.name == 'mkyong'
        Expression exp5 = parser.parseExpression("name == 'mkyong'");
        boolean msg5 = exp5.getValue(itemContext, Boolean.class);
        System.out.println(msg5);

    }
}
person myset    schedule 13.11.2017