Programmatically evaluate a bean expression with Spring Expression Language

java, spring, spring-el

Solution

implement BeanFactoryAware to get a reference to the bean factory; then...

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);

EDIT

To answer the comment below. The `@` triggers the use of the bean factory resolver to access a bean; an alternative is to add a `BeanExpressionContextAccessor` to the evaluation context and use a `BeanExpressionContext` as the root object for the evaluation...

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);

Problem

I have a simple Spring Bean Expression, which evaluates fine when I define it inside an application context file: ``` <bean id="myConfigBean" class="com.example.myBeanConfigBean"> <property name="myProperty" value="#{ someOtherBean.getData() }"/> </bean> ``` Now, I want to do the same evaluation programmatically. I have used the following code: ``` final ExpressionParser parser = new SpelExpressionParser(); final TemplateParserContext templateContext = new TemplateParserContext(); Expression expression = parser.parseExpression("#{ someOtherBean.getData() }", templateContext); final String value = (String) expression.getValue(); ``` This throws an exception: ``` EL1007E:(pos 22): Field or property 'someOtherBean' cannot be found on null ``` I guess I have to set a root object somehow that allows to the configured beans like a property. But I did not get it to work yet. Anyone, who has done this already and could give a hint?

Original source