Associatation between : SpringIocContainer | ApplicationContext | WebApplicationContext Associatation between : SpringIocContainer | ApplicationContext | WebApplicationContext spring spring

Associatation between : SpringIocContainer | ApplicationContext | WebApplicationContext


Basically, in a spring MVC application the spring contexts are registered in the servlet context of the web application. You can do that in the web.xml file setting the spring ContextLoaderListener or with java configuration. In the comments I pointed out this link where it explains how this is done via java configuration classes:

spring: where does `@autowired` look for beans?

There you can see how the 'connection' is done. Then, you asked in the comments what this achieves:

WebApplicationContextUtils.getWebApplicationContext(myServle‌​t.getServletContext(‌​))

If you check the code of that class you can see it gets the WebApplicationContext from the attributes of the ServletContext. These attributes are set in the initialization of the web application. If you notice, in the ContextLoader class (parent of ContextLoaderListener), in the initWebApplicationContext method it sets these attributes to the servlet context:

/**     * Initialize Spring's web application context for the given servlet context,     * using the application context provided at construction time, or creating a new one     * according to the "{@link #CONTEXT_CLASS_PARAM contextClass}" and     * "{@link #CONFIG_LOCATION_PARAM contextConfigLocation}" context-params.     * @param servletContext current servlet context     * @return the new WebApplicationContext     * @see #ContextLoader(WebApplicationContext)     * @see #CONTEXT_CLASS_PARAM     * @see #CONFIG_LOCATION_PARAM     */    public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {        if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {            throw new IllegalStateException(                    "Cannot initialize context because there is already a root application context present - " +                    "check whether you have multiple ContextLoader* definitions in your web.xml!");        }        Log logger = LogFactory.getLog(ContextLoader.class);        servletContext.log("Initializing Spring root WebApplicationContext");        if (logger.isInfoEnabled()) {            logger.info("Root WebApplicationContext: initialization started");        }        long startTime = System.currentTimeMillis();        try {            // Store context in local instance variable, to guarantee that            // it is available on ServletContext shutdown.            if (this.context == null) {                this.context = createWebApplicationContext(servletContext);            }            if (this.context instanceof ConfigurableWebApplicationContext) {                ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;                if (!cwac.isActive()) {                    // The context has not yet been refreshed -> provide services such as                    // setting the parent context, setting the application context id, etc                    if (cwac.getParent() == null) {                        // The context instance was injected without an explicit parent ->                        // determine parent for root web application context, if any.                        ApplicationContext parent = loadParentContext(servletContext);                        cwac.setParent(parent);                    }                    configureAndRefreshWebApplicationContext(cwac, servletContext);                }            }            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);            ClassLoader ccl = Thread.currentThread().getContextClassLoader();            if (ccl == ContextLoader.class.getClassLoader()) {                currentContext = this.context;            }            else if (ccl != null) {                currentContextPerThread.put(ccl, this.context);            }            if (logger.isDebugEnabled()) {                logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +                        WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");            }            if (logger.isInfoEnabled()) {                long elapsedTime = System.currentTimeMillis() - startTime;                logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");            }            return this.context;        }        catch (RuntimeException ex) {            logger.error("Context initialization failed", ex);            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);            throw ex;        }        catch (Error err) {            logger.error("Context initialization failed", err);            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);            throw err;        }    }

That is done in this line:

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

As you can see, it is stored in the same place where you are trying to get it with the WebApplicationContextUtils.getWebApplicationContext(myServle‌​t.getServletContext(‌​)) :

/**     * Find the root {@code WebApplicationContext} for this web app, typically     * loaded via {@link org.springframework.web.context.ContextLoaderListener}.     * <p>Will rethrow an exception that happened on root context startup,     * to differentiate between a failed context startup and no context at all.     * @param sc ServletContext to find the web application context for     * @return the root WebApplicationContext for this web app, or {@code null} if none     * @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE     */    public static WebApplicationContext getWebApplicationContext(ServletContext sc) {        return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);    }

So as you can see all the answers to your doubts are in the code that spring executes during the startup of the web application.

Hope I answered your question.


For Your Doubt 1

In an spring application there is a single instance of context Which is WebAplicationCntext per DispatcherServlet.Which can be refer by a super Interface ApplicationContext-

public class SomeThing implements ApplicationContextAware{@Overridepublic void setApplicationContext(ApplicationContext ctx) throws BeanException{//this context object is `WebApplicationContext` which is refer by `ApplicationContext`. }}

In spring , context means a just IOC container, of which some part is loaded by DispacherServlet and some part is loaded by ContextLoaderListner and can facilitate much more such as I18N,access to static resource etc

Your above understanding is almost correct.In Spring All the WebApplicationContext object shares some common reference which is rootContext.

This answer desn't include answer of doubt2, doubt3 ,and why all context perform same task.