2012-08-12 9 views
5

में प्लेसहोल्डर्स को हल नहीं करता है। मैं स्प्रिंग 3.1 प्रॉपर्टीसोर्स बनाने की कोशिश कर रहा हूं जो ज़ूकीपर नोड्स से अपने मूल्यों को पढ़ता है। जुकीपर से कनेक्ट करने के लिए मैं नेटफ्लिक्स से Curator का उपयोग कर रहा हूं।कस्टम वसंत संपत्ति स्रोत @Value

इसके लिए मैंने एक कस्टम प्रॉपर्टी स्रोत बनाया है जो जुकीपर से किसी संपत्ति के मूल्य को पढ़ता है और इसे वापस करता है। यह ठीक काम करता है जब मैं, इस

ZookeeperPropertySource zkPropertySource = new ZookeeperPropertySource(zkClient); 
ctx.getEnvironment().getPropertySources().addLast(zkPropertySource); 
ctx.getEnvironment().getProperty("foo"); // returns 'from zookeeper' 

हालांकि तरह संपत्ति को हल कर रहा हूँ जब मैं एक सेम जो एक @value टिप्पणी के साथ एक क्षेत्र तो है यह विफल करने की कोशिश का दृष्टांत:

@Component 
public class MyBean { 
    @Value("${foo}") public String foo; 
} 

MyBean b = ctx.getBean(MyBean.class); // fails with BeanCreationException 

यह समस्या है ज़ूकीपर के साथ सबसे अधिक संभावना नहीं है, लेकिन जिस तरह से मैं संपत्ति स्रोतों को पंजीकृत कर रहा हूं और सेम बना रहा हूं।

किसी भी अंतर्दृष्टि की अत्यधिक सराहना की जाती है।

अद्यतन 1:

मैं इस तरह एक XML फ़ाइल से एप्लिकेशन संदर्भ बना रहा हूं:

public class Main { 
    public static void main(String[] args) throws Exception { 
     ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 
     ctx.registerShutdownHook(); 
    } 
} 

वर्ग जो Zookeeper को जोड़ता एक @Component है।

@Component 
public class Server { 
    CuratorFramework zkClient; 

    public void connectToZookeeper() { 
     zkClient = ... (curator magic) ... 
    } 

    public void registerPropertySource() { 
     ZookeeperPropertySource zkPropertySource = new ZookeeperPropertySource(zkClient); 
     ctx.getEnvironment().getPropertySources().addLast(zkPropertySource); 
     ctx.getEnvironment().getProperty("foo"); // returns 'from zookeeper' 
    } 

    @PostConstruct 
    public void start() { 
     connectToZookeeper(); 
     registerPropertySource(); 
     MyBean b = ctx.getBean(MyBean.class); 
    } 
} 

अद्यतन 2

यह जब मैं संयोजन में एक्सएमएल-कम विन्यास का उपयोग कर रहा है, यानी @Configuration, @ComponentScan और @PropertySource एक AnnotationConfigApplicationContext के साथ काम करने लगता है। यह ClassPathXmlAplicationContext के साथ क्यों काम नहीं करता है?

@Configuration 
@ComponentScan("com.goleft") 
@PropertySource({"classpath:config.properties","classpath:version.properties"}) 
public class AppConfig { 
    @Bean 
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 
} 

उत्तर

4

अपने अद्यतन 2 के लिए उत्तर देना: यह अपने मूल विन्यास के साथ काम नहीं करता है इस समय तक क्योंकि PropertySource बहुत देर से पंजीकृत किया जा रहा है, (एक PropertySource @PostConstruct उपयोग करके उसे पंजीकृत) अपने लक्ष्य सेम पहले से ही निर्माण किया गया है और प्रारंभ।

आम तौर पर प्लेसहोल्डर्स का इंजेक्शन BeanFactoryPostProcessor के माध्यम से होता है जो स्प्रिंग लाइफसाइक्ल में बहुत जल्दी होता है (इस चरण में बीन्स नहीं बनाए गए हैं) और यदि उस चरण में एक प्रॉपर्टीसोर्स पंजीकृत है, तो प्लेसहोल्डर्स को हल किया जाना चाहिए।

public class CustomInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext> { 
    public void initialize(ConfigurableWebApplicationContext ctx) { 
     ZookeeperPropertySource zkPropertySource = new ZookeeperPropertySource(zkClient); 
     ctx.getEnvironment().getPropertySources().addFirst(zkPropertySource); 
    } 
} 
+0

आप अपने अद्यतन में भी AppConfig कोड शामिल करें कर सकते हैं:

सबसे अच्छा तरीका है, हालांकि एक ApplicationContextInitializer उपयोग करने के लिए, applicationContext पर एक संभाल पाने और वहाँ propertySource रजिस्टर करने के लिए है। –

+0

मैंने समस्या को सरल बना दिया है लेकिन अब मैं इसे और काम नहीं कर सकता। यह हमेशा कॉन्फ़िगरेशन फ़ाइल से लोड होता है। खैर, असल में यह मेरे गैर-सरलीकृत प्रोजेक्ट में काम करता है लेकिन केवल AppConfig क्लास के साथ और जब config config.properties फ़ाइल में मौजूद नहीं है। मैं गैर-वेबैप के साथ ApplicationContextInitializer का उपयोग कैसे करूं? – magiconair

+1

हाँ, आप सही हैं, यह थोड़ा अलग काम करता है। मैंने आपको अपने भंडार में एक परीक्षण के साथ एक पुल अनुरोध भेजा है जो एनोटेशन और एक्सएमएल आधारित अनुप्रयोग संदर्भ के लिए लगातार व्यवहार करता है। –

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