2010-12-16 3 views
5

Мы обновляем наши приложения с Spring 2.5 до 3.0, и мы столкнулись с проблемой новой оценки свойств bean-объектов.Spring 3: отключить оценку Spel стоимости бина?

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

например.

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

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

Альтернативно существует способ избежать значений?

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

ответ

2

Ну что вы могли бы сделать, это заново определить языковые выражения разделителей.

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

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, используйте новые разделители.

EDIT: сейчас я проверил его, и он действительно работает.

<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
# {стрела()}

4

Полностью отключить оценку 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"/> 
+0

`BeanFactoryPostProcessor` - это, конечно, умнее использовать (+1). Я соответственно изменю свой ответ – 2010-12-17 08:13:05

Смежные вопросы