24

मैं वसंत, जो मैं ठीक करने में असमर्थ हूँ का उपयोग कर काम पर अपनी परियोजनाओं में से एक में एक वृत्तीय संदर्भ है, और स्टार्टअप पर निम्न त्रुटि के साथ विफल:स्प्रिंग वृत्तीय संदर्भ उदाहरण

'org.springframework.security.authenticationManager': Requested bean is currently in creation: Is there an unresolvable circular reference? 

मैं करने की कोशिश की एक नमूना परियोजना में एक छोटे से स्तर पर एक ही समस्या को फिर से बनाएं (मेरे कार्य प्रोजेक्ट के सभी विवरणों के बिना)। हालांकि मैं एक व्यावहारिक परिदृश्य के साथ आने में असमर्थ रहा हूं जहां वसंत एक त्रुटि के साथ विफल रहता है। यहाँ मैं क्या है:

public class ClassA { 
    @Autowired 
    ClassB classB; 
} 

public class ClassB { 
    @Autowired 
    ClassC classC; 
} 

@Component 
public class ClassC { 
    @Autowired 
    ClassA classA; 
} 

@Configuration 
public class Config { 
    @Bean 
    public ClassA classA() { 
     return new ClassA(); 
    } 

    @Bean 
    public ClassB classB() { 
     return new ClassB(); 
    } 
} 

मैं अपने प्रोजेक्ट है, जो विफल रहता है में एक समान परिदृश्य है, और मैं अपने नमूना परियोजना में शिकायत करने के लिए और साथ ही वसंत उम्मीद कर रहा था। लेकिन यह ठीक काम करता है! क्या कोई मुझे परिपत्र संदर्भ त्रुटि के साथ वसंत तोड़ने का एक सरल उदाहरण दे सकता है?

संपादित करें: मैंने javax.inject.Provider का उपयोग करके समस्या को ठीक किया। 2 परियोजनाओं में एकमात्र अन्य अंतर था एनोटेशन का इस्तेमाल किया गया था javax.inject.Inject और javax.annotation.ManagedBean @Autowired और @Component के स्थान पर।

उत्तर

23

यह एक पुराना धागा है, इसलिए मुझे लगता है कि आप लगभग इस मुद्दे के बारे में भूल गए हैं, लेकिन मैं आपको रहस्य के बारे में बताना चाहता हूं। मुझे एक ही समस्या का सामना करना पड़ा, और मेरा जादूगर से दूर नहीं गया, इसलिए मुझे समस्या का समाधान करना पड़ा। मैं आपके प्रश्नों को चरण-दर-चरण हल कर दूंगा।

1. आप परिपत्र संदर्भ अपवाद को पुन: उत्पन्न क्यों नहीं कर सके?

क्योंकि Spring takes care of it. It creates beans and injects them as required

2. फिर आपकी परियोजना अपवाद क्यों उत्पन्न करती है?

  • रूप @sperumal कहा, यदि आप निर्माता इंजेक्शन का उपयोग
  • लॉग के अनुसार वसंत परिपत्र अपवाद उत्पादन हो सकता है, आप अपने प्रोजेक्ट
  • स्प्रिंग सुरक्षा config में वसंत सुरक्षा का उपयोग, वे निर्माता का उपयोग करते हैं इंजेक्शन
  • आपका सेम जो authenticationManager injects

3. फिर वृत्तीय संदर्भ था क्यों पूर्व है रहस्यमय रूप से ception चले गए?

अपवाद हो सकता है या नहीं हो सकता है सेम के निर्माण आदेश पर निर्भर करता है। मैं तुम्हें कई *context.xml फाइल या तो बना लगता है, और web.xml

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>classpath:*-context.xml</param-value> 
</context-param> 

एक्सएमएल फ़ाइलें XmlWebApplicationContext वर्ग और फ़ाइलों के लदान आदेश से लोड किया जाएगा गारंटी नहीं है में नीचे की तरह config कुछ के साथ उन्हें लोड। यह सिर्फ फाइल सिस्टम से फाइल लोड करता है। समस्या यहाँ है। कक्षा में एप्लिकेशन संदर्भ फ़ाइल को पहले लोड करने में कोई समस्या नहीं है, क्योंकि आपकी बीन्स पहले से ही बनाई गई हैं जब वे वसंत सुरक्षा के निर्माण इंजेक्शन के लिए उपयोग की जाती हैं। लेकिन, अगर यह स्प्रिंग सिक्योरिटी संदर्भ फ़ाइल को पहले लोड करता है, तो सर्कुलर संदर्भ समस्या होती है, क्योंकि स्प्रिंग आपके बीन्स का निर्माण करने से पहले कन्स्ट्रक्टर इंजेक्शन में उपयोग करने की कोशिश करता है।

4. समस्या का समाधान कैसे करें?

एक्सएमएल फाइलों के लोडिंग ऑर्डर को बल दें। मेरे मामले में, मैंने <import resource=""> का उपयोग करके एप्लिकेशन संदर्भ फ़ाइल के अंत में सुरक्षा संदर्भ xml फ़ाइल लोड की। लोडिंग ऑर्डर बदला जा सकता है, उसी कोड के साथ भी वातावरण पर निर्भर करता है, इसलिए मैं संभावित समस्याओं को दूर करने के लिए ऑर्डर सेट करने की सलाह देता हूं।

2

इस मामले पर कुछ पढ़ने:

http://blog.jdevelop.eu/?p=382

इस तरह के परिपत्र निर्भरता शांत नहीं हैं और जब भी संभव हो

26

आप @Lazy इस्तेमाल कर सकते हैं संकेत मिलता है कि सेम lazily बनाई गई है परहेज किया जाएगा, को तोड़ने autowiring के उत्सुक चक्र।

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

@Lazy एनोटेशन @Configuration साथ संयोजन के रूप में इस्तेमाल किया जा सकता संकेत मिलता है कि कि विन्यास वर्ग के भीतर सभी सेम lazily प्रारंभ होना चाहिए:

वसंत-Jira में एक अंक से

। बेशक, @Lazy का उपयोग के साथ व्यक्तिगत @ बीन विधियों के साथ भी किया जा सकता है ताकि पर एक-एक-एक आधार पर आलसी प्रारंभिक संकेत दिया जा सके। https://jira.springsource.org/browse/SJC-263

मतलब है कि @Lazy के रूप में अपने सेम व्याख्या पर्याप्त होगा। या यदि आपने अभी @Lazy के रूप में विन्यास वर्ग व्याख्या पसंद करते हैं इस प्रकार है:

@Configuration 
@Lazy 
public class Config { 
    @Bean 
    public ClassA classA() { 
     return new ClassA(); 
    } 

    @Bean 
    public ClassB classB() { 
     return new ClassB(); 
    } 
} 

आप अपने सेम यह काफी अच्छी तरह से काम करेंगे की एक इंटरफ़ेस को लागू है।

+1

बस इसमें जोड़ने के लिए, हमने एक समान समस्या (SpringTemplateEngine के इंजेक्शन के साथ) मारा। "सेटर इंजेक्शन" समाधान में मदद नहीं मिली, लेकिन '@ Lazy' एनोटेशन ने चाल की। यह बुलेट घाव पर बैंड-एड्स की तरह लगता है, लेकिन अभी के लिए मैं जीत ले जाऊंगा और चले जाऊंगा। धन्यवाद मिस्टर Spaeth। – demaniak

9

वसंत दस्तावेज़ीकरण के अनुसार, कन्स्ट्रक्टर इंजेक्शन का उपयोग कर सर्कुलर निर्भरता समस्या या BeanCurrentlyInCreationException प्राप्त करना संभव है।

समस्या को हल करने का समाधान कन्स्ट्रक्टर इंजेक्शन के बजाय सेटर्स का उपयोग करना है।

संदर्भ http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html

+2

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

+1

कन्स्ट्रक्टर इंजेक्शन सेटर इंजेक्शन पर कन्स्ट्रक्टर इंजेक्शन बेहतर है - आपका बीन तब तक मौजूद नहीं है जब तक कि कन्स्ट्रक्टर आमंत्रण पूरा नहीं हो जाता है, जबकि सेटर इंजेक्शन के साथ आप कुछ आवश्यक पैरामीटर छोड़ सकते हैं और बीन कुछ समय के लिए ठीक से कॉन्फ़िगर नहीं किया गया है –

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