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


    在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.下面就不再赘述,详情参考上面两节

  • 相关阅读:
    【c语言】使用NULL和指针来寻找数组中是否存在指定的数字
    【c语言】利用指针求三个数的最大数和最小数
    【c语言】统计一个整数所包含的素因子并输出
    【c语言】比较两个分数的大小
    心情
    matlab
    越来越懒了
    研究生学习
    谢谢
    elasticsearch 索引
  • 原文地址:https://www.cnblogs.com/davidwang456/p/2956125.html
Copyright © 2020-2023  润新知