2015-01-16 9 views
40

में @ बीन एनोटेटेड विधि को कॉल करना मैं उत्सुक हूं कि वसंत इंजेक्शन @Bean एनोटेशन के साथ कॉलिंग विधियों को कैसे प्रबंधित करता है। अगर मैं एक विधि पर @Bean एनोटेशन डालता हूं, और एक उदाहरण देता हूं, तो मैं समझता हूं कि स्प्रिंग को विधि को कॉल करके और लौटा हुआ उदाहरण प्राप्त करके एक बीन बनाने के लिए कहा जाता है। हालांकि, कभी-कभी उस बीन को अन्य बीन्स को तारने या अन्य कोड सेट करने के लिए उपयोग किया जाना चाहिए। ऐसा करने का सामान्य तरीका उदाहरण प्राप्त करने के लिए @Bean एनोटेटेड विधि को कॉल करना है। मेरा सवाल यह है कि, क्यों यह बीन के चारों ओर तैरने के कई उदाहरण नहीं होने का कारण बनता है?स्प्रिंग जावा कॉन्फ़िगरेशन

उदाहरण के लिए, नीचे दिए गए कोड को देखें (किसी अन्य प्रश्न से लिया गया)। entryPoint() विधि @Bean के साथ एनोटेटेड है, इसलिए मुझे लगता है कि वसंत BasicAuthenticationEntryPoint का एक नया उदाहरण बन जाएगा। फिर, हम कॉन्फ़िगर ब्लॉक में entryPoint() को फिर से कॉल करते हैं, लेकिन ऐसा लगता है कि entryPoint() बीन इंस्टेंस देता है, और इसे कई बार नहीं कहा जाता है (मैंने लॉगिंग करने का प्रयास किया, और केवल एक लॉग प्रविष्टि प्राप्त की)। संभावित रूप से हम कॉन्फ़िगरेशन के अन्य हिस्सों में entryPoint() कई बार कॉल कर सकते हैं, और हम हमेशा एक ही उदाहरण प्राप्त करेंगे। क्या यह मेरी सही समझ है? वसंत @Bean के साथ एनोटेटेड विधियों के कुछ जादुई पुनर्लेखन करता है?

@Bean 
public BasicAuthenticationEntryPoint entryPoint() { 
    BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint(); 
    basicAuthEntryPoint.setRealmName("My Realm"); 
    return basicAuthEntryPoint; 
} 

@Override 
protected void configure(HttpSecurity http) throws Exception { 

    http 
     .exceptionHandling() 
      .authenticationEntryPoint(entryPoint()) 
      .and() 
     .authorizeUrls() 
      .anyRequest().authenticated() 
      .and() 
     .httpBasic();  
} 

उत्तर

61

हाँ, स्प्रिंग कुछ जादू करता है। चेक Spring Docs:

सभी @Configuration कक्षाएं CGLIB साथ स्टार्टअप समय पर subclassed कर रहे हैं। उप-वर्ग में, बच्चे विधि किसी भी कैश किए गए (स्कॉप्ड) सेम के लिए पहले कंटेनर को जांचती है, इससे पहले कि वह पैरेंट विधि को कॉल करे और एक नया उदाहरण तैयार करे।

इसका मतलब है कि @Bean तरीकों को अपने कॉल CGLIB के माध्यम से प्रॉक्सी रहे हैं और इसलिए सेम का संचित संस्करण दिया जाता है (एक नया एक नहीं बनाई गई है)।

एस का डिफ़ॉल्ट दायरा SINGLETON है, यदि आप PROTOTYPE जैसे एक अलग दायरे को निर्दिष्ट करते हैं तो कॉल मूल विधि को पास कर दिया जाएगा।

+0

क्या इस तरह से बनाए गए सेम को ओवरराइड करना संभव है? उदाहरण के लिए, मेरे पास स्प्रिंग परिभाषित कक्षा है जो सीधे बीन निर्माण विधि को कॉल करती है। मैं जो चाहता हूं वह यह है कि उस विधि द्वारा बनाई गई बीन का उपयोग नहीं किया जाता है, लेकिन एक मैं खुद को परिभाषित करता हूं (इसे '@ बीन' और' प्राथमिक 'के साथ टिप्पणी करके)। – Fons

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