2010-12-16 10 views
5

Estamos en el proceso de actualización de nuestras aplicaciones de la primavera 2,5 a 3,0 y hemos alcanzado un problema con la nueva evaluación SpEL de las propiedades del bean.Resorte 3: desactivar la evaluación de SpEL de un valor de propiedad de frijol?

Hemos estado utilizando una sintaxis de plantillas en la casa en un módulo que, desgraciadamente, utiliza el mismo "# {xyz}" markup como SpEL. Tenemos unos cuantos granos que tienen cuerdas de que contiene estas expresiones como propiedades pero la primavera supone que son expresiones SPEL y lanza un SpelEvaluationException cuando se trata de una instancia del frijol.

p. Ej.

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

¿Es posible desactivar la evaluación SpEL, idealmente per-frijol, pero, alternativamente, para todo el contexto de la aplicación?

Alternativamente hay una manera de escapar de los valores?

Gracias, Stephen

Respuesta

2

Bueno lo que podría hacer es volver a definir los delimitadores de lenguaje de expresión.

Yo diría que la manera de hacer esto es a través de un grano especial que implementa BeanFactoryPostProcessor (gracias a la inspiración de Jim 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; 
     } 
    } 

} 

definirlo como un grano de la siguiente manera:

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

o como esto:

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

o utilizar una resolución personalizada:

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

Ahora usted puede dejar sus definiciones intacto y si desea utilizar SpEL, utilizar los nuevos delimitadores.

EDIT: ahora Lo probé y realmente funciona. código

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

prueba:

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

Salida:

/home/seanizer
/tmp
# {pluma()}

4

desactivar completamente la evaluación SpEL llamando al método fábrica de beans setBeanExpressionResolver que pasa en null. Puede definir un BeanFactoryPostProcessor para hacer esto.

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

Defina este bean en el contexto de la aplicación.

<bean class="com.example.spel.DisableSpel"/> 
+0

'BeanFactoryPostProcessor' es, por supuesto, la cosa más inteligente de usar (+1). Voy a cambiar mi propia respuesta en consecuencia –

Cuestiones relacionadas