我们正在将我们的应用程序从Spring 2.5更新到3.0,并且我们遇到了新的SpEL评估bean属性的问题。
我们一直在一个模块中使用内部模板语法,不幸的是,它使用与SpEL相同的“#{xyz}”标记。我们有一些bean将包含这些表达式的字符串作为属性,但是spring假定它们是SpEL表达式,并在尝试实例化bean时抛出SpelEvaluationException。
e.g。
<bean id="templatingEngine" class="com.foo.TemplatingEngine">
<property name="barTemplate" value="user=#{uid}&country=#{cty}"/>
</bean>
是否可以禁用SpEL评估,理想情况下是每个bean,但是对于整个应用程序上下文也是如此?
或者有办法逃避价值吗?
谢谢, 斯蒂芬
答案 0 :(得分:4)
通过调用传入null
的bean工厂setBeanExpressionResolver方法完全禁用SpEL评估。您可以定义BeanFactoryPostProcessor
来执行此操作。
public class DisableSpel implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory)
throws BeansException
{
beanFactory.setBeanExpressionResolver(null);
}
}
然后在应用程序上下文中定义此bean。
<bean class="com.example.spel.DisableSpel"/>
答案 1 :(得分:2)
您可以做的是重新定义表达式语言分隔符。
我想说这样做的方法是通过一个实现BeanFactoryPostProcessor
的特殊bean(感谢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;
}
}
}
将它定义为这样的bean:
<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()}
答案 2 :(得分:0)
我不是一个轻拍,但这是一个帮助。