वसंत @PostConstruct बनाम init- विधि विशेषता


103

क्या स्प्रिंग एक्सएमएल कॉन्फ़िगरेशन में @PostConstructएनोटेशन का उपयोग करने और उसी विधि की घोषणा करने के बीच कोई अंतर init-methodहै?

जवाबों:


153

व्यावहारिक रूप से मुझे नहीं लगता कि इसमें कोई अंतर है लेकिन उनके काम करने के तरीके में प्राथमिकताएं हैं। @PostConstruct, init-methodबीनपोस्टप्रोसेसर हैं।

  1. @PostConstructएक जेएसआर -50 एनोटेशन है, जबकि init-methodस्प्रिंग का एक प्रारंभिक विधि होने का तरीका है।
  2. यदि आपके पास एक @PostConstructविधि है, तो शुरुआती तरीकों को कॉल करने से पहले इसे पहले कहा जाएगा।
  3. यदि आपका बीन इनिशियलाइज़िंग बीन लागू करता है और ओवरराइड करता है afterPropertiesSet, तो पहले @PostConstructकॉल किया जाता है, फिर afterPropertiesSetऔर फिर init-method

अधिक जानकारी के लिए आप स्प्रिंग के संदर्भ प्रलेखन की जांच कर सकते हैं ।

JSR 250 स्पेक्स से पहले, xml में init-method का उपयोग करना पसंद किया गया था, क्योंकि यह किसी भी स्प्रिंग विशिष्ट कक्षाओं / एनोटेशन से java क्लासेस (बीन्स) को डिकम्पोज करता है। यदि आप एक लाइब्रेरी का निर्माण कर रहे हैं, जिसे स्प्रिंग इंफ्रास्ट्रक्चर बीन्स पर निर्भर होने की आवश्यकता नहीं है तब init-method का उपयोग पसंद किया गया था। निर्माण की विधि u को वह विधि निर्दिष्ट कर सकती है जिसे आरंभीकरण विधि के रूप में कहा जाना चाहिए।

अब जावा ईई में जेएसआर 250 चश्मा और इन एनोटेशन के वसंत समर्थन की शुरूआत के साथ, वसंत ढांचे पर निर्भरता कुछ हद तक कम हो गई है।

लेकिन मुझे यह स्वीकार करना होगा कि इन चीजों के अलावा कोड की पठनीयता में वृद्धि होती है। इसलिए, दोनों दृष्टिकोणों के पक्ष और विपक्ष हैं।


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

2
@ डॉनल काफी सच है। बस यह कैसे काम करता है के बारे में जानकारी प्रदान कर रहा था।
अरविंद ए

1
एक महत्वपूर्ण अंतर है: आपको विशेष रूप से @PostConstruct काम करने के लिए एनोटेशन को संसाधित करने के लिए स्प्रिंग को कॉन्फ़िगर करने की आवश्यकता है: stackoverflow.com/q/3434377/134898
जुआन कैलेरो

@ डोनॉफेलोज़, लेकिन आपको यह जानने की आवश्यकता है कि क्या आप प्रमाणन परीक्षा लेने की योजना बना रहे हैं?)
एस

@ डोनल फेलो - क्या आप कृपया अपना उत्तर विस्तृत कर सकते हैं? मेरा मतलब है कि अगर एक बीन आरंभीकरण के आदेश पर निर्भर करता है, तो कठिनाइयों का सामना करना पड़ता है। वास्तव में मैं जानना चाहता हूं कि कौन सा बेहतर है। PostConstruct या बीन (initMethod = "init") अपने अनुरोधों को पूरा करने से पहले बीन से कुछ इनिशियलाइज़ेशन सामान करना?
आयस्केंट

19

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


4

@ पॉस्टकंस्ट्रक्ट वसंत का हिस्सा नहीं है। यह javax पैकेज का हिस्सा है। दोनों एक ही हैं। init-method का उपयोग करके हमें xml फ़ाइल में जोड़ा जाना चाहिए। यदि आप xp में @postconstruct को जोड़ने का उपयोग करते हैं, तो आवश्यक नहीं है। नीचे दिए गए लेख को देखें।

http://answersz.com/spring-postconstruct-and-predestroy/


3

जैसा कि आप बीन क्रिएशन लाइफ-साइकल कॉलबैक के नीचे आरेख में देख सकते हैं ।

बीन क्रिएशन लाइफ-साइकल कॉलबैक

यह 3 चरण बीन क्रिएशन लाइफ-साइकल कॉलबैक में होता है:

  1. यह उल्लेख @PostConstructकिया जाता है कि कहा जाएगा।
  2. अगर InitializingBeanलागू afterPropertiesSet()किया जाता है , तो बुलाया जाएगा।
  3. यदि बीन की परिभाषा सम्‍मिलित है init-methodया @Bean(initmethod="..")फिर यह init विधि कहती है।

यह आरेख प्रो स्प्रिंग 5: एन-डेप्थ गाइड टू द स्प्रिंग फ्रेमवर्क और इसके टूल्स से है


3

के बीच अंतर हो सकता है@PostConstruct और init-methodक्योंकि सेम इनिशियलाइज़ेशन ( विधि) @PostConstructके postProcessAfterInitializationचरण में संभाला जाता AbstractAutowireCapableBeanFactory.initializeBean()है CommonAnnotationBeanPostProcessor, जबकि चरण initके पूरा होने के बाद विधि को बुलाया जाता है postProcessBeforeInitialization(और, इस मामले के लिए, postProcessAfterInitializationचरण की शुरुआत से पहले )।
EDIT : तो, अनुक्रम है: 1) postProcessBeforeInitializationचरण, 2) initविधि को बुलाया जाता है, 3) postProcessAfterInitializationचरण, जिसे @PostConstructविधि कहा जाता है

(एक साइड नोट के रूप में, स्वीकृत उत्तर से एक बयान

@PostConstruct, init-पद्धति बीनपोस्टप्रोसेसर है

बिलकुल सही नहीं है: @PostConstructएक के द्वारा नियंत्रित किया जाता है BeanPostProcessor, initविधि नहीं है।)

वहाँ हो जाएगा अंतर अगर कुछ (संभावित कस्टम) BeanPostProcessor, जिसके साथ कॉन्फ़िगर किया गया है ( Ordered.getOrder()) के बाद निष्पादित किया जाना है CommonAnnotationBeanPostProcessor, कुछ अपने में गंभीर कर रहा है postProcessBeforeInitializationविधि।
वहाँ नहीं है के डिफ़ॉल्ट स्प्रिंग विन्यास के साथ कोई फर्क BeanPostProcessorsक्योंकि सभी BeanPostProcessorsजिसके बाद निष्पादित करने के लिए कॉन्फ़िगर किया गया है CommonAnnotationBeanPostProcessor, में कुछ भी नहीं करते postProcessBeforeInitializationविधि।

निष्कर्ष में, स्वीकृत जवाब और समान सही हैं ... 99% मामलों में, और यह पोस्ट सिर्फ एक अवधारणा "श्रद्धांजलि विवरण में है" के लिए श्रद्धांजलि देने के लिए है


नमस्ते! यह भ्रामक है, यदि PostConstruct init-method से पहले चलता है, तो यह postProcessAfterInitialisation द्वारा कैसे संभाला जाता है यदि init मेथड PostprocessBeforeInitialization के बाद और पोस्टप्रोसेसऑउट इनऑर्गेनाइजेशन से पहले चलता है ???
मैक्सरनर

@Maxrunner, भ्रम के लिए खेद है और पता करने के लिए बहुत धन्यवाद! वास्तव में, मेरा यह कहने का कभी मतलब नहीं था कि पोस्टकॉस्ट्रिट init-method से पहले चलता है। वैसे भी, मैंने कुछ स्पष्टीकरणों के साथ अपना जवाब अपडेट किया
igor.zh

2

यहाँ पूर्ण कोड: https://github.com/wkaczurba/so8519187 ( वसंत-बूट )

एनोटेशन का उपयोग करना:

@Slf4j
@Component
public class MyComponent implements InitializingBean {

    @Value("${mycomponent.value:Magic}")
    public String value;

    public MyComponent() {
        log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null
    }

    @PostConstruct
    public void postConstruct() {
        log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
    }

    @Override // init-method; overrides InitializingBean.afterPropertiesSet()
    public void afterPropertiesSet() {
        log.info("MyComponent in afterPropertiesSet: [{}]", value);  // (2) displays: Magic
    }   

    @PreDestroy
    public void preDestroy() {
        log.info("MyComponent in preDestroy: [{}]", value); // (3) displays: Magic
    }
}

हमें हो जाता है:

ताज़ा करना org.springframework.context ...

कंस्ट्रक्टर में MyComponent: [null]
MyCponent in postConstruct: [Magic]
MyComponent in afterPropertiesSet: [मैजिक]
...

स्टार्टअप पर JMX एक्सपोज़र के लिए बीन्स रजिस्टर
करना 0.561 सेकंड में शुरू किया गया डेमोफ्लेक्शंस (JVM 1.011 पर चल रहा है)
समापन org.springframework.context । बंद पर JMX उजागर सेम Unregistering

...
PreDestroy में MyComponent: [जादू]

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