स्प्रिंग को वर्तमान ApplicationContext मिलता है


105

मैं अपने वेब एप्लिकेशन के लिए स्प्रिंग एमवीसी का उपयोग कर रहा हूं। मेरी सेम " spring-servlet.xml" फाइल में लिखी गई है

अब मेरे पास एक क्लास है MyClassऔर मैं स्प्रिंग बीन का उपयोग करके इस क्लास को एक्सेस करना चाहता हूं

में spring-servlet.xmlमैं लिखा है निम्नलिखित

<bean id="myClass" class="com.lynas.MyClass" />

अब मुझे इसका उपयोग करने की आवश्यकता है ApplicationContext

ApplicationContext context = ??

ताकि मैं कर सकूं

MyClass myClass = (MyClass) context.getBean("myClass");

यह कैसे करना है??


3
@Autowired MyClass myClass को काम करना चाहिए!
मन्नकेनपिक्स

जवाबों:


160

बस इसे इंजेक्ट करें ..

@Autowired
private ApplicationContext appContext;

या इस इंटरफ़ेस को लागू करें: ApplicationContextAware


शायद यह काम कर सकता है: stackoverflow.com/questions/11682858/…
gipinani

निम्नलिखित ApplicationContextProvider.javaउत्तर इसके लिए सबसे विश्वसनीय समाधान लगता है।
आयनुत

1
यह हर बार NULL लौट रहा है। यहाँ उल्लेख करने के लिए कि मैं एक सामान्य वर्ग के अंदर ऐसा कर रहा हूँ जो न तो "@RestController" है और न ही "@Component" है
zulkarnain shah

1
स्प्रिंग डॉक्यूमेंटेशन के अनुसार, कुछ मुद्दों के कारण @Autowired से बचना सबसे अच्छा है। यहाँ लिंक spring.io/understanding/application-context है । सबसे अच्छा विकल्प ApplicationContextAware इंटरफ़ेस को लागू करने के साथ जाना है।
दुरजा आराई

89

मुझे लगता है कि यह लिंक गैर-बीन वर्ग में भी कहीं भी एप्लिकेशन संदर्भ प्राप्त करने का सबसे अच्छा तरीका दर्शाता है। मुझे यह बहुत उपयोगी लगता है। आशा है कि आप के लिए भी ऐसा ही होगा। नीचे इसका सार कोड दिया गया है

एक नया वर्ग बनाएँ ApplicationContextProvider.java

package com.java2novice.spring;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ApplicationContextProvider implements ApplicationContextAware{

    private static ApplicationContext context;

    public static ApplicationContext getApplicationContext() {
        return context;
    }

    @Override
    public void setApplicationContext(ApplicationContext ac)
            throws BeansException {
        context = ac;
    }
}

Application-reference.xml में एक प्रविष्टि जोड़ें

<bean id="applicationContextProvider"
                        class="com.java2novice.spring.ApplicationContextProvider"/>

एनोटेशन मामले में (आवेदन-संदर्भ के बजाय। xml)

@Component
public class ApplicationContextProvider implements ApplicationContextAware{
...
}

इस तरह संदर्भ प्राप्त करें

TestBean tb = ApplicationContextProvider.getApplicationContext().getBean("testBean", TestBean.class);

चीयर्स !!


1
मैंने विवेक के समान कोड किया। लेकिन मैं नए ApplicationContextProvider () बनाने से बचता हूं, क्योंकि मुझे संदर्भ से गेटबैन () को कॉल करने की आवश्यकता होती है। मैंने जो किया वह स्थैतिक ApplicationContextProvider.getApplicationContext() तरीका था। फिर, जब वर्तमान एप्लिकेशन संदर्भ की आवश्यकता होती है, तो मैं आह्वान करता हूं:ApplicationContextProvider appContext = ApplicationContextProvider.getApplicationContext()
पाणिनी लंचर

1
हाँ पाणिनी लंचर, यह अभी भी अच्छा होगा। आपके सुझाव के अनुसार मैं इसे इस तरह बदल दूंगा। :)
विवेक

4
जोड़ें @Componentपर ApplicationContextProviderमें विन्यास से बच सकते हैंaplication-context.xml
BlueArrow

1
नोट: संदर्भ के गेटर और सेटर को सिंक्रनाइज़ किया जाना चाहिए। आप विशेष रूप से इकाई / एकीकरण-परीक्षणों के लिए बहुत अधिक सिरदर्द से बचेंगे। मेरे मामले में इसी तरह के ApplicationContextProvider ने पुराने संदर्भ (पिछले एकीकरण परीक्षण से) का आयोजन किया जो बहुत सारे मुश्किल कीड़े थे।
ओलेक्ज़ेंडर_डीजे

43

मामले में आपको एक HttpServlet के भीतर से संदर्भ का उपयोग करने की आवश्यकता है जो स्वयं स्प्रिंग द्वारा त्वरित नहीं है (और इसलिए न तो @Autowire और न ही ApplicationContextAware काम करेगा) ...

WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());

या

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

अन्य उत्तरों में से कुछ के लिए, ऐसा करने से पहले दो बार सोचें:

new ClassPathXmlApplicationContext("..."); // are you sure?

... क्योंकि यह आपको वर्तमान संदर्भ नहीं देता है, बल्कि यह आपके लिए इसका एक और उदाहरण बनाता है। जिसका अर्थ है कि 1) मेमोरी का महत्वपूर्ण हिस्सा और 2) बीन्स को इन दो एप्लिकेशन संदर्भों के बीच साझा नहीं किया गया है।


SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (यह) - ने मेरे लिए लाइफ़्रे पोर्टलेट एक्शन फ़िल्टर इनिट () विधि का काम किया।
इगोर बैबोरोडाइन 12

बहुत बढ़िया, processInjectionBasedOnCurrentContext ने मेरी ज़रूरत के सभी काम किए। बहुत धन्यवाद @Jaroslav
Jad B.

ApplicationContextAware मेरे लिए काम करता है, जब इसे विवेक के समाधान के रूप में @Component के साथ एनोटेट किया जाता है (मैं वसंत संदर्भ को मैन्युअल रूप से बढ़ा रहा हूं AbstractContextLoaderInitializer / createRerApplicationContext के माध्यम से)
hello_earth

सावधान रहें ... SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (यह); तुरंत नहीं होता है, इसलिए आप इसे उदाहरण के लिए अपने निर्माता की पहली पंक्ति के रूप में उपयोग नहीं कर सकते।
स्लेजामेमर

31

यदि आप एक वर्ग लागू कर रहे हैं जो स्प्रिंग द्वारा त्वरित नहीं है, तो एक JsonDeserializer की तरह जिसका आप उपयोग कर सकते हैं:

WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
MyClass myBean = context.getBean(MyClass.class);

8
यह मेरे लिए काम नहीं करता है। मेरी कक्षा स्प्रिंग संदर्भ से बाहर है। मैंने आपके कोड का उपयोग करने की कोशिश की है, लेकिन यह मुझे प्रतिक्रिया के रूप में एक अशक्त देता है । मैं बात कर रहा हूँContextLoader.getCurrentWebApplicationContext()
आर। कर्लूस

9

इसे अपने कोड में जोड़ें

@Autowired
private ApplicationContext _applicationContext;

//Add below line in your calling method
MyClass class = (MyClass) _applicationContext.getBean("myClass");

// Or you can simply use this, put the below code in your controller data member declaration part.
@Autowired
private MyClass myClass;

यह बस आपके आवेदन में myClass इंजेक्षन करेगा


6

विवेक के जवाब पर आधारित है, लेकिन मुझे लगता है कि निम्नलिखित बेहतर होगा:

@Component("applicationContextProvider")
public class ApplicationContextProvider implements ApplicationContextAware {

    private static class AplicationContextHolder{

        private static final InnerContextResource CONTEXT_PROV = new InnerContextResource();

        private AplicationContextHolder() {
            super();
        }
    }

    private static final class InnerContextResource {

        private ApplicationContext context;

        private InnerContextResource(){
            super();
        }

        private void setContext(ApplicationContext context){
            this.context = context;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return AplicationContextHolder.CONTEXT_PROV.context;
    }

    @Override
    public void setApplicationContext(ApplicationContext ac) {
        AplicationContextHolder.CONTEXT_PROV.setContext(ac);
    }
}

यदि एक से अधिक उदाहरणों में हेराफेरी की जा रही है, तो इंस्टेंट फील्ड से स्टैटिक फील्ड में लिखना एक बुरा अभ्यास और खतरनाक है।


नहीं है org.springframework.core.io.ContextResourceइंटरफ़ेस। मैं ContextResourceकेवल गड़बड़ से बचने के लिए आंतरिक वर्ग के लिए अलग नाम चुनने का सुझाव दूंगा।
अलेक्जेंडर रेडचेंको

@AlexanderRadchenko ठीक है, मैंने इसे बदलकर इनरकोनटेक्स्ट। स्रोत
जुआन

1

स्प्रिंग एप्लिकेशन में एप्लिकेशन संदर्भ प्राप्त करने के कई तरीके हैं। उन लोगों को दिया जाता है:

  1. ViaContextAware :

    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    public class AppContextProvider implements ApplicationContextAware {
    
    private ApplicationContext applicationContext;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    }

यहाँ पर setApplicationContext(ApplicationContext applicationContext)आपको applicationContext मिलेगा

  1. स्‍वचालित :

    @Autowired
    private ApplicationContext applicationContext;

यहां @Autowiredकीवर्ड एप्लीकेशनकनेक्ट उपलब्ध कराएगा।

अधिक जानकारी के लिए इस धागे पर जाएँ

धन्यवाद :)


0

एक और तरीका है सर्वलेट के माध्यम से ApplicationContext को इंजेक्ट करें।

यह स्प्रिंग वेब सेवाओं का उपयोग करते समय निर्भरता को कैसे नियंत्रित किया जाए, इसका एक उदाहरण है।

<servlet>
        <servlet-name>my-soap-ws</servlet-name>
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
        <init-param>
            <param-name>transformWsdlLocations</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:my-applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>5</load-on-startup>

</servlet>

वैकल्पिक तरीका यह है कि अपने web.xml में आवेदन प्रसंग जोड़ें। जैसा कि नीचे दिखाया गया है

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/classes/my-another-applicationContext.xml
        classpath:my-second-context.xml
    </param-value>
</context-param>

मूल रूप से आप सर्वलेट को यह बताने की कोशिश कर रहे हैं कि यह इन संदर्भ फाइलों में परिभाषित सेम के लिए दिखना चाहिए।


0

चरण 1 : कक्षा में निम्नलिखित कोड इंजेक्ट करें

@Autowired
private ApplicationContext _applicationContext;

चरण 2 : लिखने वाला और सेटर लिखें

चरण 3 : xml फ़ाइल में ऑटोवायर = "बाईटाइप" को परिभाषित करें जिसमें बीन को परिभाषित किया गया है


0

@Autowire को जोड़ने के बाद भी यदि आपकी कक्षा एक RestController या कॉन्फ़िगरेशन वर्ग नहीं है, तो ApplicationContext ऑब्जेक्ट शून्य के रूप में आ रहा था। नीचे के साथ नई कक्षा बनाने की कोशिश की और यह ठीक काम कर रहा है:

@Component
public class SpringContext implements ApplicationContextAware{

   private static ApplicationContext applicationContext;

   @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws 
     BeansException {
    this.applicationContext=applicationContext;
   }
 }

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

    applicationContext.getBean(String serviceName,Interface.Class)

-11
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-servlet.xml");

फिर आप बीन को पुनः प्राप्त कर सकते हैं:

MyClass myClass = (MyClass) context.getBean("myClass");

संदर्भ: springbyexample.org


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