随笔 - 1677  文章 - 615 评论 - 432 trackbacks - 0

在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_PARAM
10      * @see #CONFIG_LOCATION_PARAM
11      */
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 that
32             // 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.下面就不再赘述,详情参考上面两节

posted on 2013-03-12 17:24 一天不进步,就是退步 阅读(...) 评论(...) 编辑 收藏