वसंत में ApplicationContextAware कैसे काम करता है?


82

वसंत में, यदि कोई बीन लगाता है ApplicationContextAware, तो वह उस तक पहुंचने में सक्षम होता है applicationContext। इसलिए यह अन्य फलियाँ प्राप्त करने में सक्षम है। जैसे

public class SpringContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;     

    public void setApplicationContext(ApplicationContext context) throws BeansException {
      applicationContext = context;
    }

    public static ApplicationContext getApplicationContext() {
      return applicationContext;
    }
}

फिर SpringContextUtil.getApplicationContext.getBean("name")बीन "नाम" प्राप्त कर सकते हैं।

ऐसा करने के लिए, हमें इसे SpringContextUtilअंदर रखना चाहिए applications.xml, जैसे

<bean class="com.util.SpringContextUtil" />

यहाँ बीन SpringContextUtilमें संपत्ति शामिल नहीं है applicationContext। मुझे लगता है कि जब स्प्रिंग बीन इनिशियलाइज़ होता है, तो यह प्रॉपर्टी सेट हो जाती है। लेकिन यह कैसे किया जाता है? विधि को कैसे setApplicationContextकहा जाता है?


13
वसंत जादू है। जादू को गले लगाओ
rosenthal

जवाबों:


99

जब स्प्रिंग बीन्स को तात्कालिक करता है, तो यह कुछ इंटरफेस की तरह दिखता है जैसे ApplicationContextAwareऔर InitializingBean। यदि वे पाए जाते हैं, तो तरीकों को लागू किया जाता है। जैसे (बहुत सरलीकृत)

Class<?> beanClass = beanDefinition.getClass();
Object bean = beanClass.newInstance();
if (bean instanceof ApplicationContextAware) {
    ((ApplicationContextAware) bean).setApplicationContext(ctx);
}

ध्यान दें कि नए संस्करण में वसंत-विशिष्ट इंटरफेस को लागू करने के बजाय एनोटेशन का उपयोग करना बेहतर हो सकता है। अब आप बस उपयोग कर सकते हैं:

@Inject // or @Autowired
private ApplicationContext ctx;

4
बहुत बहुत धन्यवाद, यही मैं चाहता हूँ! शायद मुझे यह समझने के लिए कुछ स्प्रिंग कोड पढ़ने की ज़रूरत है कि वसंत कैसे काम करता है।
जिमी

2
ज्यादातर मामलों के लिए @Autowired का उपयोग करना बेहतर होता है, लेकिन कुछ ऐसे भी हैं, जो काम नहीं कर सकते हैं, उदाहरण के लिए जब आपके पास "@Component" होता है, जो एक सिंगलटन होता है, लेकिन आपको एक सेम को इंजेक्ट करने की आवश्यकता होती है जिसमें एक सत्र गुंजाइश होती है। जैसा कि निर्भरताएँ अनुप्रयोग संदर्भ निर्माण में स्वत: प्राप्त होती हैं, आपके पास सत्र बीन इंजेक्ट नहीं होगा, आवेदन संदर्भ के संदर्भ में आप सत्र बीन को प्रोग्रामेटिक रूप से प्राप्त कर सकते हैं जो सत्र बीन आवृत्ति को सही ढंग से वापस कर देगा।
रास्पाकॉर्प जूल

मुझे उम्मीद है कि स्प्रिंग इसके बजाय गतिशील रूप से उत्पन्न प्रॉक्सी वर्ग को इंजेक्ट करेगा - इस तरह के वर्ग में अनुप्रयोग गुंजाइश होती है, लेकिन जब इसे एक्सेस किया जाता है, तो यह एक सत्र गुंजाइश उदाहरण को
दर्शाता है

@raspacorp यदि एक सेसन गुंजाइश बीन को इंजेक्शन से नहीं मिला जा सकता है ApplicationContext, तो यह ApplicationContextAware instanceया तो नहीं मिल सकता है । क्योंकि ApplicationContextAware instanceजिस applicationContextवस्तु को इंजेक्ट किया जाता है उसी वस्तु से बीन मिलती है ।
टिआना

10

स्प्रिंग सोर्स कोड यह समझाने के लिए कि
जब आप क्लास ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
में ApplicationContextAware काम करते हैं AbstractApplicationContext, तो refresh()विधि में निम्नलिखित कोड होते हैं:

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

इस विधि को दर्ज करें, beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));AbstractCBtextAwareProcessor को AbstractrBeanFactory में जोड़ देगा।

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
        // Configure the bean factory with context callbacks.
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
...........

जब वसंत AbstractAutowireCapableBeanFactoryविधि में बीन को इनिशियलाइज़ करता है , तो बीन पोस्ट प्रक्रिया को लागू करने के लिए initializeBeanकॉल करें applyBeanPostProcessorsBeforeInitialization। इस प्रक्रिया में एप्लिकेशनकॉन्टेक्ट इंजेक्ट करें।

@Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
        Object result = existingBean;
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
            if (result == null) {
                return result;
            }
        }
        return result;
    }

जब बीनपोस्टप्रोसेसर ऑब्जेक्ट को लागू करता है, तो पोस्टप्रोसेसबियरइन्फ्लेमेटाइजेशन विधि निष्पादित करें, उदाहरण के लिए ApplicationContextAwareProcessorजो पहले जोड़ा गया था।

private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof EnvironmentAware) {
                ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
            }
            if (bean instanceof EmbeddedValueResolverAware) {
                ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
                        new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
            }
            if (bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
            }
            if (bean instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
            }
            if (bean instanceof MessageSourceAware) {
                ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
            }
            if (bean instanceof ApplicationContextAware) {
                ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
            }
        }
    }

0

किसी भी ऑब्जेक्ट द्वारा लागू किया जाने वाला इंटरफ़ेस जिसे एप्लिकेशनकेनटेक्स्ट के अधिसूचित किए जाने की इच्छा है, जो इसमें चलता है।

ऊपर स्प्रिंग डॉक्टर वेबसाइट https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context-ApplicationContextAware.html से लिया गया है।

इसलिए, ऐसा प्रतीत होता है कि वसंत कंटेनर शुरू हो गया है, यदि आप उस समय कुछ करना चाहते हैं।

यह सिर्फ संदर्भ स्थापित करने की एक विधि है, इसलिए आप संदर्भ प्राप्त करेंगे और पहले से ही मेरे विचार से sth के लिए कुछ करेंगे।


-1

ApplicationContextAware इंटरफ़ेस, वर्तमान अनुप्रयोग संदर्भ, जिसके माध्यम से आप स्प्रिंग कंटेनर सेवाओं को लागू कर सकते हैं। हम क्लास में विधि द्वारा नीचे इंजेक्ट किए गए वर्तमान एप्लिकेशन कॉन्टेक्स्ट उदाहरण प्राप्त कर सकते हैं

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