2009-07-06 13 views
8

पर गुणों को पास करना मैं कुछ दूरस्थ सर्वर पर आरएमआई कॉल को संभालने के लिए वसंत का उपयोग कर रहा हूं। यह ग्राहक के भीतर से दूरदराज के आमंत्रण के लिए सेम एक आवेदन संदर्भ का निर्माण और प्राप्त करने के लिए स्पष्ट है:वसंत संदर्भ

ApplicationContext context = new ApplicationContext("classpath:context.xml"); 

MyService myService = (MyService) context.getBean("myService "); 

हालांकि मैं विन्यास में गुण पारित करने के लिए एक आसान तरीका नहीं दिख रहा। उदाहरण के लिए यदि मैं क्लाइंट के भीतर रनटाइम पर रिमोट सर्वर के लिए होस्ट नाम निर्धारित करना चाहता हूं।

मैं आदर्श रूप में इस तरह स्प्रिंग संदर्भ में एक प्रवेश होगा:

<bean id="myService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"> 
    <property name="serviceUrl" value="rmi://${webServer.host}:80/MyService"/> 
    <property name="serviceInterface" value="com.foo.MyService"/> 
</bean> 

और एक पैरामीटर के रूप ग्राहक से संदर्भ के लिए गुण गुजरती हैं।

मैं इन गुणों के विकल्प के संदर्भ में संदर्भ में एक PropertyPlaceholder कॉन्फ़िगरर का उपयोग कर सकता हूं, लेकिन जहां तक ​​मैं यह कह सकता हूं कि यह केवल फाइल से पढ़ने वाले गुणों के लिए काम करता है।

मेरे पास एक कार्यान्वयन है जो इसे संबोधित करता है (एक उत्तर के रूप में जोड़ा गया) लेकिन मैं अपने खुद के रोलिंग से बचने के लिए एक मानक वसंत कार्यान्वयन की तलाश में हूं। क्या कॉन्फ़िगरेशन शुरू करने में मदद करने के लिए कोई और स्प्रिंग कॉन्फ़िगरर (या कुछ और) है या क्या मैं इसे प्राप्त करने के लिए जावा कॉन्फ़िगरेशन को बेहतर तरीके से देख रहा हूं?

+0

अपनी प्रॉपर्टी और कहाँ की दुकान है? –

+0

क्लाइंट किसी भी सर्वर से कनेक्ट हो सकता है, उदा। उपयोगकर्ता होस्ट नाम को टेक्स्ट फ़ील्ड में टाइप कर सकता है। तो यह संकलन समय पर निर्धारित नहीं है। –

उत्तर

1

अद्यतन:

सवाल अद्यतन के आधार पर, मेरा सुझाव है:

  1. एक ServiceResolver सेम बनाएं जो संभालती है जो कुछ भी आप ग्राहक इनपुट के आधार पर संभाल करने की जरूरत है;
  2. इस बीन को प्रासंगिक सेवाओं की निर्भरता के रूप में घोषित करें;
  3. रनटाइम पर, आप इस बीन को अपडेट/उपयोग कर सकते हैं हालांकि आप फिट देखते हैं।

ServiceResolver कर सकते हैं तो, या तो init-method पर या प्रत्येक मंगलाचरण पर मान निर्धारित करता है, उदा के आधार पर ग्राहक के लिए वापस जाने के लिए जेएनडीआई लुकअप या पर्यावरण चर।

लेकिन ऐसा करने से पहले, आप configuration options पर एक नज़र डालना चाहेंगे। आप या तो कर सकते हैं:

  • संपत्ति फ़ाइलों को जोड़ें जो संकलन समय पर मौजूद नहीं हैं;
  • जेएनडीआई से मूल्य देखें;
  • सिस्टम.प्रोपर्टीज से मूल्य प्राप्त करें।

आप एक कस्टम स्थान से गुण देखने के लिए की जरूरत है, org.springframework.beans.factory.config.BeanFactoryPostProcessor पर एक नज़र डालें और org.springframework.beans.factory.config.PropertyPlaceholderConfigurer कैसे कार्यान्वित किया जाता है।

मूल विचार यह है कि आप 'कच्चे' गुणों के साथ सेम प्राप्त करते हैं, उदाहरण के लिए ${jdbcDriverClassName} और फिर आप उन्हें हल करने और वांछित मूल्यों के साथ उन्हें बदलने के लिए मिलता है।

+0

धन्यवाद इस प्रकार मेरा मौजूदा कार्यान्वयन यह करता है, मैं इसे प्रतिबिंबित करने के लिए अपना प्रश्न अपडेट करूंगा। मैं उम्मीद कर रहा था कि इसके लिए एक मानक वसंत कार्यान्वयन है इसलिए मैं अपना खुद का रोलिंग से बच सकता हूं। –

1

PropertyPlaceholder कॉन्फ़िगरर फ़ाइल से गुण प्राप्त कर सकता है, यह सच है, लेकिन यदि यह उन्हें नहीं मिल रहा है, तो यह सिस्टम गुणों का उपयोग करने के लिए वापस आ जाता है।यह आपके क्लाइंट एप्लिकेशन के लिए व्यवहार्य विकल्प की तरह लगता है, जब आप क्लाइंट लॉन्च करते हैं तो बस डीडी का उपयोग करने में सिस्टम प्रॉपर्टी पास करें।

javadoc

से एक configurer भी प्रणाली गुण (जैसे, "user.dir") यदि यह निर्दिष्ट गुण के किसी भी साथ एक प्लेसहोल्डर का समाधान नहीं कर के खिलाफ जाँच करेगा। यह "systemPropertiesMode" के माध्यम से अनुकूलित किया जा सकता है।

2

मेरे मौजूदा समाधान में एक नया MapAwareAplicationContext परिभाषित करना शामिल है जो एक अतिरिक्त कन्स्ट्रक्टर तर्क के रूप में मानचित्र लेता है।

protected void postProcessBeanFactory(
    final ConfigurableListableBeanFactory beanFactory) { 
    beanFactory.addBeanPostProcessor(new MapAwareProcessor(this.map)); 
    beanFactory.ignoreDependencyInterface(MapAware.class); 
} 

MapAwareProcessor postProcessBeforeInitialization() को लागू करता है किसी भी प्रकार कि MapAware इंटरफ़ेस लागू करता है में नक्शा सुई:

public Object postProcessBeforeInitialization(final Object bean, 
     final String beanName) { 
    if (this.map != null && bean instanceof MapAware) { 
     ((MapAware) bean).setMap(this.map); 
    } 

    return bean; 
} 

public MapAwareApplicationContext(final URL[] configURLs, 
    final String[] newConfigLocations, 
    final Map<String, String> additionalProperties) { 
    super(null); 

    //standard constructor content here 

    this.map = new HashMap<String, String>(additionalProperties); 

    refresh(); 
} 

यह postProcessBeanFactory() एक MapAwareProcessor में जोड़ने के लिए ओवरराइड करता है

फिर मै मैपवेयरप्रॉपर्टीप्लेसहोल्डर कॉन्फ़िगरर घोषित करने के लिए अपनी कॉन्फ़िगरेशन में एक नया बीन जोड़ता हूं:

<bean id="propertyConfigurer" 
    class="com.hsbc.r2ds.spring.MapAwarePropertyPlaceholderConfigurer"/> 

कॉन्फ़िगरर MapAware लागू करता है, इसलिए इसे उपरोक्त मानचित्र के साथ इंजेक्शन दिया जाएगा। अपने कोड में सीधे

protected String resolvePlaceholder(final String placeholder, 
     final Properties props, final int systemPropertiesMode) { 
    String propVal = null; 
    if (this.map != null) { 
     propVal = this.map.get(placeholder); 
    } 
    if (propVal == null) { 
     propVal = super.resolvePlaceholder(placeholder, props); 
    } 
    return propVal; 
} 
+1

अच्छा भगवान, यह एक साधारण समस्या का एक जटिल समाधान है ... – skaffman

+0

यह मेरी तरह का मुद्दा है, ऐसा लगता है कि बहुत अधिक प्रयास किए बिना इसे प्राप्त करने योग्य होना चाहिए, इस –

+0

से निश्चित रूप से कम प्रयास करें या आप बीनफैक्टरीपोस्टप्रोसेसर का उपयोग कर सकते हैं: http://springindepth.com/book/in-depth-ioc-bean- बाद प्रोसेसर और beanFactory-बाद processors.html – Talijanac

0

एक RmiProxyFactoryBean इंस्टेंस बनाएं और कॉन्फ़िगर serviceUrl संपत्ति: यह तो resolvePlaceholder() मानचित्र से गुण को हल करने, या माता-पिता configurer प्रतिनिधि को लागू करता है

String serverHost = "www.example.com"; 

RmiProxyFactoryBean factory = new RmiProxyFactoryBean(); 
factory.setServiceUrl("rmi://" + serverHost + ":80/MyService"); 
factory.setServiceInterface(MyService.class); 
try { 
    factory.afterPropertiesSet(); 
} catch (Exception e) { 
    throw new RuntimeException(
      "Problem initializing myService factory", e); 
} 
MyService myService = (MyService) factory.getObject(); 
13

http://forum.springsource.org/showthread.php?t=71815 देखें

TestClass.java

package com.spring.ioc; 

public class TestClass { 

    private String first; 
    private String second; 

    public String getFirst() { 
     return first; 
    } 

    public void setFirst(String first) { 
     this.first = first; 
    } 

    public String getSecond() { 
     return second; 
    } 

    public void setSecond(String second) { 
     this.second = second; 
    } 
} 

SpringStart.java

package com.spring; 

import java.util.Properties; 

import com.spring.ioc.TestClass; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; 

public class SpringStart { 
    public static void main(String[] args) throws Exception { 
    PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer(); 
    Properties properties = new Properties(); 
    properties.setProperty("first.prop", "first value"); 
    properties.setProperty("second.prop", "second value"); 
    configurer.setProperties(properties); 

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(); 
    context.addBeanFactoryPostProcessor(configurer); 

    context.setConfigLocation("spring-config.xml"); 
    context.refresh(); 

    TestClass testClass = (TestClass)context.getBean("testBean"); 
    System.out.println(testClass.getFirst()); 
    System.out.println(testClass.getSecond()); 
    } 
} 

spring-config.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation=" 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 

    <bean id="testBean" class="com.spring.ioc.TestClass"> 
     <property name="first" value="${first.prop}"/> 
     <property name="second" value="${second.prop}"/> 
    </bean> 

</beans> 

आउटपुट:

first value 
second value 
संबंधित मुद्दे