Spring 3: отключить SpEL-оценку значения свойства бина? - PullRequest
5 голосов
/ 16 декабря 2010

Мы находимся в процессе обновления наших приложений с Spring 2.5 до 3.0, и у нас возникла проблема с новой оценкой SpEL свойств bean-компонента.

Мы использовали собственный шаблонный синтаксис в одном модуле, который, к сожалению, использует ту же самую разметку "# {xyz}", что и SpEL. У нас есть несколько bean-компонентов, которые принимают строки, содержащие эти выражения, как свойства, но spring предполагает, что они являются выражениями SpEL, и выдает исключение SpelEvaluationException, когда пытается создать экземпляр компонента.

, например

<bean id="templatingEngine" class="com.foo.TemplatingEngine">
   <property name="barTemplate" value="user=#{uid}&country=#{cty}"/>
</bean>

Можно ли отключить оценку SpEL, в идеале для каждого компонента, но в качестве альтернативы для всего контекста приложения?

В качестве альтернативы есть способ избежать значений?

Спасибо, Стивен

Ответы [ 3 ]

5 голосов
/ 16 декабря 2010

Полностью отключите оценку SpEL, вызвав фабрику бинов setBeanExpressionResolver метод, передающий null. Вы можете определить BeanFactoryPostProcessor для этого.

public class DisableSpel implements BeanFactoryPostProcessor {
    public void postProcessBeanFactory(
        ConfigurableListableBeanFactory beanFactory)
        throws BeansException
    {
        beanFactory.setBeanExpressionResolver(null);
    }
}

Затем определите этот компонент в контексте приложения.

<bean class="com.example.spel.DisableSpel"/>
2 голосов
/ 16 декабря 2010

Что вы можете сделать, это переопределить разделители языка выражений.

Я бы сказал, что это можно сделать с помощью специального компонента, который реализует BeanFactoryPostProcessor (благодаря вдохновению Джима Хуанга):

public class ExpressionTokensRedefiner implements BeanFactoryPostProcessor{

    private BeanExpressionResolver beanExpressionResolver;

    public void setBeanExpressionResolver(
        final BeanExpressionResolver beanExpressionResolver){
        this.beanExpressionResolver = beanExpressionResolver;
    }

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

    private String expressionPrefix = "${";
    private String expressionSuffix = "}";

    public void setExpressionPrefix(final String expressionPrefix){
        this.expressionPrefix = expressionPrefix;
    }
    public void setExpressionSuffix(final String expressionSuffix){
        this.expressionSuffix = expressionSuffix;
    }

    private BeanExpressionResolver createResolver(){
        if(beanExpressionResolver == null){
            final StandardBeanExpressionResolver resolver =
                new StandardBeanExpressionResolver();
            resolver.setExpressionPrefix(expressionPrefix);
            resolver.setExpressionSuffix(expressionSuffix);
            return resolver;
        } else{
            return beanExpressionResolver;
        }
    }

}

Определите это как боб, как это:

<bean class="foo.bar.ExpressionTokensRedefiner">
    <property name="expressionPrefix" value="[[" />
    <property name="expressionSuffix" value="]]" />
</bean>

или как это:

<!-- this will use the default tokens ${ and } -->
<bean class="foo.bar.ExpressionTokensRedefiner" />

или используйте пользовательский преобразователь:

<bean class="foo.bar.ExpressionTokensRedefiner">
    <property name="beanExpressionResolver">
        <bean class="foo.bar.CustomExpressionResolver" />
    </property>
</bean>

Теперь вы можете оставить свои определения без изменений, и если вы хотите использовать SpEL, используйте новые разделители.

РЕДАКТИРОВАТЬ: Теперь я проверил его, и он на самом деле работает.

<bean class="foo.bar.ExpressionTokensRedefiner">
    <property name="expressionPrefix" value="[[" />
    <property name="expressionSuffix" value="]]" />
</bean>


<bean class="foo.bar.FooFritz">
    <property name="fizz" value="[[ systemProperties['user.home'] ]]"></property>
    <property name="fozz" value="[[ systemProperties['java.io.tmpdir'] ]]"></property>
            <!-- this is what it would normally choke on -->
    <property name="fazz" value="#{ boom() }"></property>
</bean>

Тестовый код:

final ConfigurableApplicationContext context =
    new ClassPathXmlApplicationContext("classpath:foo/bar/ctx.xml");
context.refresh();
final FooFritz fooFritz = context.getBean(FooFritz.class);
System.out.println(fooFritz.getFizz());
System.out.println(fooFritz.getFozz());
System.out.println(fooFritz.getFazz());

Выход:

/ дом / seanizer
/ TMP
# {boom ()}

0 голосов
/ 16 декабря 2010

Я не капелька, но этот могучий помощник.

https://issues.apache.org/jira/browse/CAMEL-2599

...