बीन आरंभीकरण पूरा होने के बाद एक विधि को कैसे कॉल करें?


237

मेरे पास एक उपयोग का मामला है जहां मुझे सेम में केवल (एक बार गैर-स्थैतिक) विधि को कॉल करने की आवश्यकता होती है, एक बार ApplicationContext लोड पर। क्या यह ठीक है, अगर मैं इसके लिए MethodInvokingFactoryBean का उपयोग करूं? या हमारे पास कुछ बेहतर उपाय है?

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

यह अच्छी तरह से कैसे किया जा सकता है?

जवाबों:


196

आप कुछ का उपयोग कर सकते हैं जैसे:

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

यह "इनिट" विधि को बुलाएगा जब बीन को तत्काल किया जाएगा।


15
PostConstruct ज्यादातर मामलों में बेहतर होना चाहिए, हालांकि, जैसा कि हम वसंत सेम आरंभीकरण के साथ गड़बड़ नहीं करना चाहते हैं।
lwpro2

4
@ lwpro2 यहाँ "स्प्रिंग बीन इनिशियलाइज़ेशन के साथ गड़बड़ न करें" का क्या मतलब है?
यिंगवे स्नेन लिंडल

@ मार्सर ट्रेस्टी को यहां क्लास की विशेषता के लिए मुझे क्या देना चाहिए? क्या मैं यहाँ नियंत्रक वर्ग दे सकता हूँ?
KJEjava48

314

अन्य उत्तरों में @PostConstruct सुझाव पर विस्तार करने के लिए, यह मेरी राय में, वास्तव में सबसे अच्छा समाधान है।

  • यह स्प्रिंग एपीआई (@PostConstruct javax। * में है) से आपका कोड डिकोड किया जाता है।
  • यह स्पष्ट रूप से आपके init पद्धति को कुछ के रूप में एनोटेट करता है जिसे बीन को इनिशियलाइज़ करने के लिए बुलाया जाना चाहिए
  • आपको अपनी स्प्रिंग बीन परिभाषा में init-method विशेषता जोड़ने के लिए याद रखने की आवश्यकता नहीं है, स्प्रिंग स्वचालित रूप से विधि को कॉल करेगा (यह मानते हुए कि आप एनोटेशन-कॉन्फिगर विकल्प को कहीं और संदर्भ में, किसी भी तरह पंजीकृत करें)।

9
धन्यवाद, यह काम करता है। ध्यान दें कि यदि आप स्प्रिंग के साथ उपयोग करना चाहते हैं तो आपको कॉमनअनोटेशन बीनपोस्टप्रोसेसर बीन (जैसा कि ऊपर बताया गया है) रजिस्टर करने के लिए "<संदर्भ: एनोटेशन-कॉन्फिग />" शामिल होना चाहिए
ख्यालो

2
एक उपयुक्त <context:component-scan>भी काम करता है, और स्टार्टअप समय को कम करने के लिए उपयोगी हो सकता है यदि आपके पास आपके क्लासपाथ पर बड़े गैर-स्प्रिंग लाइब्रेरी हैं।
डोनल फैलो

5
PostConstruct के लिए JavaDoc का कहना है कि केवल एक विधि को प्रति वर्ग के साथ एनोटेट किया जा सकता है: docs.oracle.com/javaee/5/api/javax/annotation/…
एंड्रयू स्वान

@PostConstruct किसी लेन-देन प्रबंधक के साथ काम नहीं करता है, देखें: forum.spring.io/forum/spring-projects/data/…
mmm

2
@PostConstruct भी आपके बहुत काम का नहीं होगा जब आप जिस बीन को इंस्टेंट कर रहे हैं वह आपकी खुद की एक क्लास नहीं बल्कि कुछ थर्ड पार्टी क्लास है
John Rix

102

विचार करने के लिए तीन अलग-अलग दृष्टिकोण हैं, जैसा कि संदर्भ में वर्णित है

Init- विधि विशेषता का उपयोग करें

पेशेवरों:

  • एक इंटरफ़ेस को लागू करने के लिए बीन की आवश्यकता नहीं होती है।

विपक्ष:

  • बीन सही ढंग से कॉन्फ़िगर किया गया है यह सुनिश्चित करने के लिए निर्माण के बाद किसी भी तत्काल संकेत की आवश्यकता नहीं है।

इनिशियलाइज़िंग बीन लागू करें

पेशेवरों:

  • Init-method निर्दिष्ट करने, या घटक स्कैनिंग / एनोटेशन प्रसंस्करण चालू करने की आवश्यकता नहीं है।
  • एक पुस्तकालय के साथ आपूर्ति की गई बीन्स के लिए उपयुक्त, जहां हम इस लाइब्रेरी का उपयोग करके बीन जीवनचक्र के साथ खुद को चिंतित नहीं करना चाहते हैं।

विपक्ष:

  • Init- विधि दृष्टिकोण से अधिक आक्रामक।

JSR-250 @PostConstruct लाइफस्टाइल एनोटेशन का उपयोग करें

पेशेवरों:

  • ऑटोडेटेक्ट बीन्स को घटक स्कैनिंग का उपयोग करते समय उपयोगी।
  • यह स्पष्ट करता है कि एक विशिष्ट विधि का उपयोग आरंभीकरण के लिए किया जाना है। आशय कोड के करीब है।

विपक्ष:

  • प्रारंभिक कॉन्फ़िगरेशन में अब केंद्रीय रूप से निर्दिष्ट नहीं किया गया है।
  • आपको एनोटेशन प्रोसेसिंग चालू करना याद रखना चाहिए (जिसे कभी-कभी भुलाया जा सकता है)

4
मुझे लगता है कि यह वास्तव में @PostConstructठीक उपयोग करने के लिए एक अच्छी बात है क्योंकि यह वर्ग का हिस्सा है कि इसे आरंभीकरण प्रसंस्करण के अंत में कॉल करने की विधि की आवश्यकता है।
डोनल फैलो

अगर उस वर्ग को इसकी आवश्यकता है और आप इसे कंस्ट्रक्टर में नहीं कर सकते हैं, तो मैं इसे कोड गंध मानता हूं।
user482745

39

क्या आपने लागू करने की कोशिश की है InitializingBean? ऐसा लगता है कि आप वास्तव में क्या कर रहे हैं।

नकारात्मक पक्ष यह है कि आपका बीन वसंत-जागरूक हो जाता है, लेकिन अधिकांश अनुप्रयोगों में यह इतना बुरा नहीं है।


2
क्या कोई कारण है जो आप XML में एक init-method को निर्दिष्ट करने के लिए इंटरफ़ेस को लागू करना चुनेंगे?
मार्क

4
स्वाद का मामला है। इंटरफ़ेस स्प्रिंग घटक मॉडल का एक हिस्सा है और यह केवल उस उद्देश्य के लिए है, जबकि कस्टम नाम पद्धति के लिए यह वास्तव में स्पष्ट नहीं हो सकता है कि इसे घटक जीवनचक्र को पूरा करने के लिए बुलाया जाना है। तो यह मुख्य रूप से संचार कार्य करता है। बेशक वसंत ढांचे के लिए शुरू की निर्भरता की कमी के साथ। बीच में एक अच्छा तरीका @PostConstruct का उपयोग है, क्योंकि इसमें स्पष्ट शब्दार्थ है लेकिन निर्भरता का परिचय नहीं देता है ...
ओलिवर ड्रॉटबोहम

7
ओलिवर मुझे कुछ अच्छे बहाने देता है, लेकिन वास्तव में मैं सिर्फ init-method के बारे में भूल जाऊंगा :) एक अन्य कारण यह है कि यह प्रकार स्वयं ही जानता है कि सभी गुणों के सेट होने के बाद इसे "समाप्त" करने की आवश्यकता है - यह नहीं है मूल रूप से कुछ ऐसा जो कॉन्फ़िगरेशन में होना चाहिए
जॉन स्कीट

8

आप इसे करने के लिए अपने आवेदन के संदर्भ में एक कस्टम बीनपोस्टप्रोसेसर तैनात कर सकते हैं । या अगर आपको अपने बीन में स्प्रिंग इंटरफ़ेस लागू करने में कोई आपत्ति नहीं है, तो आप InitializingBean इंटरफ़ेस या "init-method" निर्देश (उसी लिंक) का उपयोग कर सकते हैं ।


क्या किसी के पास बीनपोस्टप्रोसेसर लिखने का विवरण है। यह वही लगता है जो मुझे चाहिए। चीयर्स :)
चोटी

कई उदाहरणों के साथ वसंत जहाज। बस बीनपोस्टप्रोसेसर के लिए जावाडॉक एपीआई देखें और आपको कई कार्यान्वयन कक्षाओं के लिंक मिलेंगे। फिर उनके लिए स्रोत कोड देखें।
रॉब एच।

-7

दो दृष्टिकोण यानी के उपयोग के बारे में किसी भी भ्रम को और स्पष्ट करने के लिए

  1. @PostConstruct तथा
  2. init-method="init"

व्यक्तिगत अनुभव से, मुझे एहसास हुआ कि (1) केवल सर्वलेट कंटेनर में काम करता है, जबकि (2) किसी भी वातावरण में काम करता है, यहां तक ​​कि डेस्कटॉप अनुप्रयोगों में भी। इसलिए, यदि आप एक स्वसंपूर्ण अनुप्रयोग में स्प्रिंग का उपयोग कर रहे हैं, तो आपको यह शुरू करने के लिए (2) का उपयोग करना होगा कि "आरंभीकरण के बाद इस पद्धति को कॉल करें।


4
तकनीकी रूप से, @PostConstruct(जब एक स्प्रिंग-आधारित ऐप में उपयोग किया जाता है) मालिक के स्प्रिंग संदर्भ के जीवन काल से जुड़ा होता है। ऐसे संदर्भों का उपयोग सभी प्रकार के अनुप्रयोगों में किया जा सकता है।
डोनल फैलो

यह वह व्यवहार था जिसकी मैं उम्मीद कर रहा था लेकिन मेरे लिए काम नहीं किया।
अयोरिंदे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.