स्प्रिंग जावा कॉन्फ़िगरेशन में @Bean एनोटेट विधि को कॉल करना


98

मैं इस बारे में उत्सुक हूं कि स्प्रिंग इंजेक्शन कैसे @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();       
}

जवाबों:


131

हां, वसंत कुछ जादू करता हैस्प्रिंग डॉक्स की जाँच करें :

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

इसका मतलब यह है कि @Beanविधियों के लिए कॉल CGLIB के माध्यम से अनुमानित हैं और इसलिए बीन का कैश्ड संस्करण वापस आ गया है (एक नया नहीं बनाया गया है)।

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

कृपया ध्यान दें कि यह स्थिर विधियों के लिए मान्य नहीं है । वसंत डॉक्स के अनुसार:

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


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

4
लेकिन मुझे यह भी याद है कि प्रॉक्सी (jdk या CGLIB, जो भी) सेल्फ-इनवोकेशन में काम नहीं कर सकता है, तो @Configuration इंटर-बीन निर्भरता को कैसे परिभाषित करता है? यह बिल्कुल आत्म-आह्वान का उपयोग करता है
Nowhy

3
@ CGLib allows us to create proxy classes at runtime by creating sub class of specified class using Byte code generation. CGLib proxies are used in the case where Proxy is to be created for those class which does not have any interfaces or have methods which are not declared in the implementing interface. इस मामले में, CGLIB @Configuration क्लास का उपवर्ग बनाता है और इसके तरीकों (@Bean पद्धति सहित) को ओवरराइड करता है। इस प्रकार, जब हम दूसरी विधि से @ बीन विधि कहते हैं, तो हम वास्तव में इसके ओवरराइड संस्करण को कहते हैं (जावा डायनामिक बाइंडिंग के लिए धन्यवाद)।
फ्लेम 239

@Componentअगर मैं जावा Poxy के बजाय परदे के पीछे बनाने के लिए CHLIB का उपयोग करता हूँ तो SelfInvocation AOP काम करेगा?
एंटोनियोसे 19
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.