11

स्प्रिंग Javaconfig संदर्भ दस्तावेज़ http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html ब्राउज़िंग मैं कुछ भ्रामक भागों मिला ...स्प्रिंग Javaconfig अंतर-सेम निर्भरता

अनुभाग "5.12.4 @Configuration एनोटेशन का उपयोग करना" के तहत यह कहते हैं:

:

"@Beans एक दूसरे पर निर्भरता है, कि निर्भरता व्यक्त एक सेम विधि एक और फोन होने के रूप में के रूप में सरल है

@Configuration public class AppConfig { @Bean public Foo foo() { return new Foo(bar()); } @Bean public Bar bar() { return new Bar(); } } 

उपर्युक्त उदाहरण में, फू बीन को कन्स्ट्रक्टर इंजेक्शन के माध्यम से बार का संदर्भ प्राप्त होता है। "

ठीक है, अगर सब कुछ राज्यविहीन है, यह हो सकता है नहीं ज्यादा बात, लेकिन अगर आप अपने आवेदन में ऊपर config है, और उसके बाद कार्य करें:

@Autowired 
private Foo foo; 

@Autowired 
private Bar bar; 

सेम के hashCodes जाँच, यह पता चला है , जो आपके निजी चर बारfoo, द्वारा इस्तेमाल किया एक से एक अलग उदाहरण की के पास भेजेगा बार जो शायद नहीं है, आप क्या उम्मीद है ना?

मैं कहूंगा कि सामान्य पैटर्न बल्कि होना चाहिए:

@Configuration 
public class AppConfig { 
    @Bean 
    public Bar bar() { 
     return new Bar(); 
    } 
    @Autowired Bar bar; 
    @Bean 
    public Foo foo() { 
     return new Foo(bar); 
    } 
} 

अब, जब आप अपने अनुप्रयोग में दोनों सेम autowire, आप केवल बार का एक उदाहरण का निर्माण करेगा।

क्या मुझे कुछ याद आ रही है, या क्या मैं सही हूं कि दस्तावेज़ीकरण यहां फ्लेकी है?

फिर, और नीचे, खंड के तहत "कैसे जावा आधारित विन्यास के बारे में अधिक जानकारी के आंतरिक रूप से काम करता है" ऐसा लगता है कि वे इस मुद्दे को "स्पष्ट" करने की कोशिश:

@Configuration 
public class AppConfig { 
    @Bean 
    public ClientService clientService1() { 
     ClientServiceImpl clientService = new ClientServiceImpl(); 
     clientService.setClientDao(clientDao()); 
     return clientService; 
    } 
    @Bean 
    public ClientService clientService2() { 
     ClientServiceImpl clientService = new ClientServiceImpl(); 
     clientService.setClientDao(clientDao()); 
     return clientService; 
    } 
    @Bean 
    public ClientDao clientDao() { 
     return new ClientDaoImpl(); 
    } 
} 

अब, दुर्भाग्यवश, यह कॉन्फ़िगरेशन, रनटाइम पर भी लोड नहीं होगा, क्योंकि एक ही प्रकार के 2 बीन्स हैं, क्लाइंट सर्विस, बिना किसी विशिष्ट गुण वाले, इसलिए अपवाद

org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type [.....] is defined: 
expected single matching bean but found 2 

लेकिन हम थोड़ा उदाहरण बदलने के लिए, और ये 2 सेम विभिन्न प्रकार देने के भले ही,

@Bean 
public ClientService1 clientService1() {...clientDao()...} 
@Bean 
public ClientService2 clientService2() {...clientDao()...} 
@Bean 
public ClientDao clientDao() { 
    return new ClientDaoImpl(); 
} 

यह अभी भी गलत है, के बाद से - क्या पाठ के दावों के विपरीत - हम अभी भी 3 अलग बन जाएगा ClientDaoImpl के उदाहरण, जब सभी 3 सेम स्वचालन करते हैं।

फिर, क्या मैं पूरी तरह से कुछ याद कर रहा हूं, या दस्तावेज वास्तव में उतना बुरा है जितना मुझे लगता है?

संपादित करें: जोड़ा एक डेमो कि इस मुद्दे को मैं देख रहा हूँ प्रदर्शन करेंगे:

https://github.com/rop49/demo

एक सेम serviceÃ, और दो सेम ServiceB1, ServiceB2 कि निर्माता-injects सेवा ए

फिर दो परीक्षण वर्गों Config01Test और Config02Test कि विन्यास को छोड़ कर एक कर रहे हैं। पहला टेस्ट पास, विशिष्टता-दावाों के कारण दूसरी विफलता।

+3

तुम्हें क्या लगता है आप अलग अलग 'Bar' वस्तुओं मिल जाएगा है में बार उसमें केवल एक ही है कि करना चाहिए? – chrylis

+0

मैंने एक छोटा परीक्षण किया, और सेम में हैशकोड की जांच की। वे भिन्न हैं। मैंने उपरोक्त प्रश्न में इसे स्पष्ट किया, धन्यवाद। – Rop

+0

किसी भी तरह से आप गिटहब पर संभवतः स्प्रिंग बूट के साथ एक साधारण चलने वाला उदाहरण पोस्ट कर सकते हैं? मैंने कभी यह व्यवहार नहीं देखा है, और यह वास्तव में हो रहा है, तो यह एक बग है। – chrylis

उत्तर

8

जांचें कि आपके पास अपनी कॉन्फ़िगरेशन क्लास पर @Configuration एनोटेशन हैं। कम से कम आपके डेमो के साथ वे Config01 और Config02 कक्षाओं से गायब हैं। यदि मैं उन वर्गों में उन्हें जोड़ता हूं तो परीक्षण पास होते हैं।

+0

आह, महान मुझे यह हल हो गया :) धन्यवाद फिल! – Rop

+0

एक साइड-नोट के रूप में ... क्या यह समझ में आता है कि स्प्रिंग अस्वीकार करने के लिए \ @SpringAplication कॉन्फ़िगरेशन है जिसमें \ @ कॉन्फ़िगरेशन एनोटेशन नहीं है? या यह कभी भी यह अनुमति देने के लिए एक वैध उपयोगकेस होगा? – Rop

+1

दुर्भाग्यवश यह बैक-संगतता को तोड़ देगा। यहां लाइट-बीन्स अनुभाग देखें: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/htmlsingle/#beans-java-basic-concepts –

0

मैं उदाहरण अपने आप को परीक्षण नहीं किया है, यह सुनिश्चित करें कि आप पूरा आवेदन संदर्भ

@Configuration 
public class AppConfig { 
    @Bean 
    public Foo foo(Bar bar) { 
     return new Foo(bar); 
    } 
    @Bean 
    public Bar bar() { 
     return new Bar(); 
    } 
} 
संबंधित मुद्दे