spring启动过程之源码跟踪(下)--spring Debug

来源:互联网 发布:php datetime 时区 编辑:程序博客网 时间:2024/06/01 23:18

在web应用启动入口是ContextLoaderListener,它是怎么完成启动过程的呢?

首先:

public class ContextLoaderListenerextends Object implements ServletContextListener//Bootstrap listener to start up Spring's root WebApplicationContext. Simply delegates to ContextLoader.//This listener should be registered after Log4jConfigListener in web.xml, if the latter is used.

public abstract interface javax.servlet.ServletContextListener extends java.util.EventListener

 

1.ContextLoaderListener.java

1     public void contextInitialized(ServletContextEvent event) {2         this.contextLoader = createContextLoader();3         this.contextLoader.initWebApplicationContext(event.getServletContext());4     }

2.ContextLoader.java

 1     /** 2      * Initialize Spring's web application context for the given servlet context, 3      * according to the "{@link #CONTEXT_CLASS_PARAM contextClass}" and 4      * "{@link #CONFIG_LOCATION_PARAM contextConfigLocation}" context-params. 5      * @param servletContext current servlet context 6      * @return the new WebApplicationContext 7      * @throws IllegalStateException if there is already a root application context present 8      * @throws BeansException if the context failed to initialize 9      * @see #CONTEXT_CLASS_PARAM10      * @see #CONFIG_LOCATION_PARAM11      */12     public WebApplicationContext initWebApplicationContext(ServletContext servletContext)13             throws IllegalStateException, BeansException {14 15         if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {16             throw new IllegalStateException(17                     "Cannot initialize context because there is already a root application context present - " +18                     "check whether you have multiple ContextLoader* definitions in your web.xml!");19         }20 21         servletContext.log("Initializing Spring root WebApplicationContext");22         if (logger.isInfoEnabled()) {23             logger.info("Root WebApplicationContext: initialization started");24         }25         long startTime = System.currentTimeMillis();26 27         try {28             // Determine parent for root web application context, if any.29             ApplicationContext parent = loadParentContext(servletContext);30 31             // Store context in local instance variable, to guarantee that32             // it is available on ServletContext shutdown.33             this.context = createWebApplicationContext(servletContext, parent);34             servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);35             currentContextPerThread.put(Thread.currentThread().getContextClassLoader(), this.context);36 37             if (logger.isDebugEnabled()) {38                 logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +39                         WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");40             }41             if (logger.isInfoEnabled()) {42                 long elapsedTime = System.currentTimeMillis() - startTime;43                 logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");44             }45 46             return this.context;47         }48         catch (RuntimeException ex) {49             logger.error("Context initialization failed", ex);50             servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);51             throw ex;52         }53         catch (Error err) {54             logger.error("Context initialization failed", err);55             servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);56             throw err;57         }58     }

3.ContextLoader.java

 1     protected WebApplicationContext createWebApplicationContext( 2             ServletContext servletContext, ApplicationContext parent) throws BeansException { 3  4         Class contextClass = determineContextClass(servletContext); 5         if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) { 6             throw new ApplicationContextException("Custom context class [" + contextClass.getName() + 7                     "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]"); 8         } 9 10         ConfigurableWebApplicationContext wac =11                 (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);12         wac.setParent(parent);13         wac.setServletContext(servletContext);14         wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));15         customizeContext(servletContext, wac);16         wac.refresh();17 18         return wac;19     }

4.回到了我们上两节提到的AbstractApplicationContext.java

    public void refresh() throws BeansException, IllegalStateException {        synchronized (this.startupShutdownMonitor) {            // Prepare this context for refreshing.            prepareRefresh();            // Tell the subclass to refresh the internal bean factory.            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);                // Invoke factory processors registered as beans in the context.                invokeBeanFactoryPostProcessors(beanFactory);                // Register bean processors that intercept bean creation.                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.                finishBeanFactoryInitialization(beanFactory);                // Last step: publish corresponding event.                finishRefresh();            }            catch (BeansException ex) {                // Destroy already created singletons to avoid dangling resources.                beanFactory.destroySingletons();                // Reset 'active' flag.                cancelRefresh(ex);                // Propagate exception to caller.                throw ex;            }        }    }

5.下面就不再赘述,详情参考上面两节