1. Create an IOC container on the web

Starting the Web server (Tomcat) loads the web. XML (ContextLoaderListener listener) :

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {

    public ContextLoaderListener(WebApplicationContext context) {
        super(context);
    }


    /** * This method is called when the serveltContext domain object is created
    @Override
    public void contextInitialized(ServletContextEvent event) {// Initialize the Spring container in the Web environment
        initWebApplicationContext(event.getServletContext());
    }


    /** * Close the root web application context. */
    @Override
    public void contextDestroyed(ServletContextEvent event) { closeWebApplicationContext(event.getServletContext()); ContextCleanupListener.cleanupAttributes(event.getServletContext()); }}Copy the code

When we click initWebApplicationContext method in May find the following the source code This method in contextLoader Namely Contextloader create the spring container and initialize the spring bean instance

try {
            // Store context in local instance variable, to guarantee that
            // it is available on ServletContext shutdown.
            if (this.context == null) {This step is to create the Spring container
                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);
                    }// The Spring container initializes instances of the singleton beanconfigureAndRefreshWebApplicationContext(cwac, servletContext); }}Copy the code

ConfigureAndRefreshWebApplicationContext method called initialization Bean refresh method in the end

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
        if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
            // The application context id is still set to its original default value
            // -> assign a more useful id based on available information
            String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
            if(idParam ! =null) {
                wac.setId(idParam);
            }
            else {
                // Generate default id...
                wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
                        ObjectUtils.getDisplayString(sc.getContextPath()));
            }
        }

        wac.setServletContext(sc);
        String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
        if(configLocationParam ! =null) {
            wac.setConfigLocation(configLocationParam);
        }

        // The wac environment's #initPropertySources will be called in any case when the context
        // is refreshed; do it eagerly here to ensure servlet property sources are in place for
        // use in any post-processing or initialization that occurs below prior to #refresh
        ConfigurableEnvironment env = wac.getEnvironment();
        if (env instanceof ConfigurableWebEnvironment) {
            ((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
        }

        customizeContext(sc, wac);
// This method is invoked in both web and Java environments to instantiate beans
        wac.refresh();
    }
Copy the code

If there is no contextClass element in web.xml, Spring will find its own contextLoad.properties file to load

# Default WebApplicationContext implementation class for ContextLoader.
# Used as fallback when no explicit context implementation has been specified as context-param.
# Not meant to be customized by application developers.

org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
Copy the code

2. How does the IOC container load bean objects

Follow the refresh() method above to his source code

The source code from AbstractApplicationContext

@Override
    public void refresh(a) throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.prepareRefresh();// create the real bean container ConfiurabaleBeanFactroy
          //2. Load beandefiniton (information describing the Bean to be initialized)

              //3. Beandefiniton is registered with the BeanDefitionRegistry
 
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

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

            try {
                // Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Execute the Bean that implements the BeanFactoryPostProcessor interface
                  / / such as accomplished (context: the property - placeholer) is invoked here, replace the placeholder BeanDefition (${}) of the content
// Invoke Factory processors registered as beans in the context
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation. / / such as container automatically loaded with a rear AutowiredAnnotationBeanPostProcessor processor (the @autowired annotation functions)
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                Instantiate all Remaining (non-lazy-init) singletons.// Instantiate all remaining (non-lazy-init) singletons This singleton can be customized with scope scope
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...resetCommonCaches(); }}}Copy the code