簡體   English   中英

Spring 3:禁用對bean屬性值的SpEL評估?

[英]Spring 3: disable SpEL evaluation of a bean property value?

我們正在將我們的應用程序從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>

是否可以禁用SpEL評估,理想情況是每個bean,但是對於整個應用程序上下文?

或者有沒有辦法逃避價值觀?

謝謝,斯蒂芬

通過調用傳入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"/>

那么你可以做的是重新定義表達式語言分隔符。

我想說這樣做的方法是通過一個實現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()}

我不是一個輕拍,但這是一個幫助。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM