• ContextLoaderListener容器初始化


    http://blog.csdn.net/qq924862077/article/details/52769754

    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>  
            classpath:applicationContext.xml  
        </param-value>  
    </context-param>  
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>

    在tomcat启动时,spring通过上述配置会初始化spring容器,注入applicationContext.xml中配置的bean以及其他一些配置

    public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
    
        public ContextLoaderListener() {
        }
        public ContextLoaderListener(WebApplicationContext context) {
            super(context);
        }
        @Override
        public void contextInitialized(ServletContextEvent event) {
            initWebApplicationContext(event.getServletContext());
        }
        @Override
        public void contextDestroyed(ServletContextEvent event) {
            closeWebApplicationContext(event.getServletContext());
            ContextCleanupListener.cleanupAttributes(event.getServletContext());
        }
    }

    ContextLoderListener实现ServletContextListener接口,而该接口继承java的监听标记接口EventListener,表示当servlet容器启动时,就会接受通知,进而进行一系列的初始化操作。

    public interface ServletContextListener extends EventListener {
    
        /**
         * Receives notification that the web application initialization
         * process is starting.
         *
         * <p>All ServletContextListeners are notified of context
         * initialization before any filters or servlets in the web
         * application are initialized.
         *
         * @param sce the ServletContextEvent containing the ServletContext
         * that is being initialized
         */
        public void contextInitialized(ServletContextEvent sce);
    
        /**
         * Receives notification that the ServletContext is about to be
         * shut down.
         *
         * <p>All servlets and filters will have been destroyed before any
         * ServletContextListeners are notified of context
         * destruction.
         *
         * @param sce the ServletContextEvent containing the ServletContext
         * that is being destroyed
         */
        public void contextDestroyed(ServletContextEvent sce);
    }

      1. 判断是否已经存在WebApplicationContext(spring容器),如果存在,则抛出异常。
      2. 创建WebApplicationContext容器,从web.xml中获取context-param名称为contextClass的value,该类必须实现WebApplicationContext接口,如果没有指定,则默认使用xmlWebApplicationContext。
      3. 判断创建的WebApplicationContext容器是否为ConfigurableApplicationContext的实例或子类,如果是,则判断该容器是否至少刷新一次并且还没有关闭(是否有效),如果无效,则重新设置容器的id,并加载对应的contextConfigLocation配置(spring配置), 
        加载父容器,spring提供一个模板方法,如果需要配置父容器,可以继承ContextLoder,并覆盖loadParentContext方法。
      4. 线程绑定容器
    /**
         * 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);
                        }
                        //如果容器无效,则重置contextId,且重新加载contextConfigLocation配置
                        configureAndRefreshWebApplicationContext(cwac, servletContext);
                    }
                }
                servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
                //线程绑定容器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;
            }
        }
  • 相关阅读:
    [笔记]Oracle遇到的问题及解决的办法
    [转载] linux三款好用网络监控软件(bwmng 、iftop、iptraf)
    IE无法打开internet站点已终止操作的解决办法 (转)
    怎样去掉桌面图标和字的蓝色阴影
    ASP.NET下载文件(转载)
    获取iframe内容IE下的延时 (转载)
    文件上传入数据库&从数据库中下载文件(转载)
    asp.net 4.0 A potentially dangerous Request.Form value was detected fr(转载)
    location.search
    IE6下的CSS BUG枚举 (转)
  • 原文地址:https://www.cnblogs.com/toov5/p/9527464.html
Copyright © 2020-2023  润新知