2010-12-16 5 views
5

हम अपने ऐप्स को स्प्रिंग 2.5 से 3.0 तक अपडेट करने की प्रक्रिया में हैं और हमने बीन गुणों के नए स्पेल मूल्यांकन के साथ एक समस्या को मारा है।वसंत 3: एक बीन संपत्ति मूल्य के स्पेल मूल्यांकन अक्षम करें?

हम एक मॉड्यूल में एक इन-हाउस टेम्पलेटिंग सिंटैक्स का उपयोग कर रहे हैं जो दुर्भाग्य से स्पेल के रूप में उसी "# {xyz}" मार्कअप का उपयोग करता है। हमारे पास कुछ बीन्स हैं जो स्ट्रिंग को गुणों के रूप में इन अभिव्यक्तियों को लेते हैं लेकिन वसंत मानते हैं कि वे स्पेल अभिव्यक्तियां हैं और जब यह बीन को तुरंत चालू करने का प्रयास करता है तो स्पेलएवल्यूएशन अपवाद को फेंकता है।

उदा।

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

क्या स्पेल मूल्यांकन को अक्षम करना संभव है, आदर्श रूप से प्रति-बीन, लेकिन वैकल्पिक रूप से पूरे एप्लिकेशन संदर्भ के लिए?

वैकल्पिक रूप से मूल्यों से बचने का कोई तरीका है?

धन्यवाद, स्टीफन

उत्तर

2

खैर तुम क्या कर सकता है फिर से परिभाषित अभिव्यक्ति भाषा सीमांकक।

मैं कहूंगा कि जिस तरह से यह करने के लिए एक विशेष सेम कि (जिम हुआंग द्वारा प्रेरणा के लिए धन्यवाद) BeanFactoryPostProcessor लागू करता है के माध्यम से है:

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

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

} 

इस तरह एक सेम के रूप में यह परिभाषित करें

या इस तरह:

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

अब आप अपनी परिभाषाओं को बिना छूटे छोड़ सकते हैं और यदि आप स्पेल का उपयोग करना चाहते हैं, तो नए डिलीमीटर का उपयोग करें।

संपादित करें: अब मैंने इसका परीक्षण किया और यह वास्तव में काम करता है।

<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

null में गुजर सेम कारखाने setBeanExpressionResolver विधि को फोन करके पूरी तरह से अक्षम स्पेल मूल्यांकन। ऐसा करने के लिए आप BeanFactoryPostProcessor को परिभाषित कर सकते हैं।

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

फिर एप्लिकेशन संदर्भ में इस बीन को परिभाषित करें।

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

'बीनफैक्टरीपोस्टप्रोसेसर 'निश्चित रूप से उपयोग करने के लिए बेहतर चीज है (+1)। मैं तदनुसार अपना जवाब बदल दूंगा –

संबंधित मुद्दे