Ste*_*hen 5 java spring javabeans
我们正在将我们的应用程序从Spring 2.5更新到3.0,并且我们遇到了新的SpEL评估bean属性的问题.
我们一直在一个模块中使用内部模板语法,遗憾的是它使用与SpEL相同的"#{xyz}"标记.我们有一些bean将包含这些表达式的字符串作为属性,但是spring假定它们是SpEL表达式,并在尝试实例化bean时抛出SpelEvaluationException.
例如
<bean id="templatingEngine" class="com.foo.TemplatingEngine">
<property name="barTemplate" value="user=#{uid}&country=#{cty}"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
是否可以禁用SpEL评估,理想情况是每个bean,但是对于整个应用程序上下文?
或者有没有办法逃避价值观?
谢谢,斯蒂芬
通过调用传入的bean工厂setBeanExpressionResolver方法,完全禁用SpEL评估null。您可以定义一个BeanFactoryPostProcessor来做到这一点。
public class DisableSpel implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory)
throws BeansException
{
beanFactory.setBeanExpressionResolver(null);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在应用程序上下文中定义此bean。
<bean class="com.example.spel.DisableSpel"/>
Run Code Online (Sandbox Code Playgroud)
那么你可以做的是重新定义表达式语言分隔符。
我想说,做到这一点的方法是通过一个特殊的 bean 来实现BeanFactoryPostProcessor(感谢 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
将其定义为一个 bean,如下所示:
<bean class="foo.bar.ExpressionTokensRedefiner">
<property name="expressionPrefix" value="[[" />
<property name="expressionSuffix" value="]]" />
</bean>
Run Code Online (Sandbox Code Playgroud)
或者像这样:
<!-- this will use the default tokens ${ and } -->
<bean class="foo.bar.ExpressionTokensRedefiner" />
Run Code Online (Sandbox Code Playgroud)
或使用自定义解析器:
<bean class="foo.bar.ExpressionTokensRedefiner">
<property name="beanExpressionResolver">
<bean class="foo.bar.CustomExpressionResolver" />
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
现在您可以保持定义不变,如果您想使用 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>
Run Code Online (Sandbox Code Playgroud)
测试代码:
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());
Run Code Online (Sandbox Code Playgroud)
输出:
/home/seanizer
/tmp
#{ 繁荣 () }