Tomcat8.5源码分析-ContextConfig

来源:互联网 发布:农业物联网大数据平台 编辑:程序博客网 时间:2024/05/22 02:02

ContextConfig

还是先看看源码,看一下这个监听器做了什么。

public void lifecycleEvent(LifecycleEvent event) {        // Identify the context we are associated with        try {            context = (Context) event.getLifecycle();        } catch (ClassCastException e) {            log.error(sm.getString("contextConfig.cce", event.getLifecycle()),                    e);            return;        }        // Process the event that has occurred        if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {            configureStart();// 里面调用了webConfig()        } else if (event.getType().equals(Lifecycle.BEFORE_START_EVENT)) {            beforeStart();        } else if (event.getType().equals(Lifecycle.AFTER_START_EVENT)) {            // Restore docBase for management tools            if (originalDocBase != null) {                context.setDocBase(originalDocBase);            }        } else if (event.getType().equals(Lifecycle.CONFIGURE_STOP_EVENT)) {            configureStop();        } else if (event.getType().equals(Lifecycle.AFTER_INIT_EVENT)) {            init();        } else if (event.getType().equals(Lifecycle.AFTER_DESTROY_EVENT)) {            destroy();        }    }

接着看configureStart():

protected synchronized void configureStart() {        // Called from StandardContext.start()        if (log.isDebugEnabled()) {            log.debug(sm.getString("contextConfig.start"));        }        if (log.isDebugEnabled()) {            log.debug(sm.getString("contextConfig.xmlSettings",                    context.getName(),                    Boolean.valueOf(context.getXmlValidation()),                    Boolean.valueOf(context.getXmlNamespaceAware())));        }        webConfig();/* 这个方法解析了web.xml文件 */        if (!context.getIgnoreAnnotations()) {            applicationAnnotationsConfig();        }        if (ok) {            validateSecurityRoles();        }        // Configure an authenticator if we need one        if (ok) {            authenticatorConfig();        }        // Dump the contents of this pipeline if requested        if (log.isDebugEnabled()) {            log.debug("Pipeline Configuration:");            Pipeline pipeline = context.getPipeline();            Valve valves[] = null;            if (pipeline != null) {                valves = pipeline.getValves();            }            if (valves != null) {                for (int i = 0; i < valves.length; i++) {                    log.debug("  " + valves[i].getClass().getName());                }            }            log.debug("======================");        }        // Make our application available if no problems were encountered        if (ok) {            context.setConfigured(true);        } else {            log.error(sm.getString("contextConfig.unavailable"));            context.setConfigured(false);        }    }

接着看webConfig:

    protected void webConfig() {        /*         * Anything and everything can override the global and host defaults.         * This is implemented in two parts - Handle as a web fragment that gets         * added after everything else so everything else takes priority - Mark         * Servlets as overridable so SCI configuration can replace         * configuration from the defaults         */        /*         * The rules for annotation scanning are not as clear-cut as one might         * think. Tomcat implements the following process: - As per SRV.1.6.2,         * Tomcat will scan for annotations regardless of which Servlet spec         * version is declared in web.xml. The EG has confirmed this is the         * expected behaviour. - As per         * http://java.net/jira/browse/SERVLET_SPEC-36, if the main web.xml is         * marked as metadata-complete, JARs are still processed for SCIs. - If         * metadata-complete=true and an absolute ordering is specified, JARs         * excluded from the ordering are also excluded from the SCI processing.         * - If an SCI has a @HandlesType annotation then all classes (except         * those in JARs excluded from an absolute ordering) need to be scanned         * to check if they match.         */        WebXmlParser webXmlParser = new WebXmlParser(                context.getXmlNamespaceAware(), context.getXmlValidation(),                context.getXmlBlockExternal());        Set<WebXml> defaults = new HashSet<>();        defaults.add(getDefaultWebXmlFragment(webXmlParser));        WebXml webXml = createWebXml();        // Parse context level web.xml        // 解析context级的web.xml        InputSource contextWebXml = getContextWebXmlSource();        if (!webXmlParser.parseWebXml(contextWebXml, webXml, false)) {// 解析web.xml并创建对象            ok = false;        }        ServletContext sContext = context.getServletContext();        // Ordering is important here        // 顺序在这里很重要        // Step 1. Identify all the JARs packaged with the application and those        // provided by the container. If any of the application JARs have a        // web-fragment.xml it will be parsed at this point. web-fragment.xml        // files are ignored for container provided JARs.        // 第一步 .识别所有的JARs 包用那些container提供的应用。如果有任何应用JARs有web-fragment.xml将在此刻解析        // 对于那些提供了JARs的container,web-fragment.xml被忽略。        Map<String, WebXml> fragments = processJarsForWebFragments(webXml,                webXmlParser);        // Step 2. Order the fragments.        // 第二步,给碎片进行排序        Set<WebXml> orderedFragments = null;        orderedFragments = WebXml                .orderWebFragments(webXml, fragments, sContext);        // Step 3. Look for ServletContainerInitializer implementations        // 查找ServletContainerInitializer的实现        if (ok) {            processServletContainerInitializers();        }        if (!webXml.isMetadataComplete() || typeInitializerMap.size() > 0) {            // Step 4. Process /WEB-INF/classes for annotations and            // @HandlesTypes matches            // 第四步.为注释传递 /WEB-INF.classes ,处理类型匹配            Map<String, JavaClassCacheEntry> javaClassCache = new HashMap<>();            if (ok) {                WebResource[] webResources = context.getResources()                        .listResources("/WEB-INF/classes");                for (WebResource webResource : webResources) {                    // Skip the META-INF directory from any JARs that have been                    // expanded in to WEB-INF/classes (sometimes IDEs do this).                    if ("META-INF".equals(webResource.getName())) {                        continue;                    }                    processAnnotationsWebResource(webResource, webXml,                            webXml.isMetadataComplete(), javaClassCache);                }            }            // Step 5. Process JARs for annotations and            // @HandlesTypes matches - only need to process those fragments we            // are going to use (remember orderedFragments includes any            // container fragments)            // 第5步 为annotations 传递JARs            if (ok) {                processAnnotations(orderedFragments,                        webXml.isMetadataComplete(), javaClassCache);            }            // Cache, if used, is no longer required so clear it            javaClassCache.clear();        }        if (!webXml.isMetadataComplete()) {            // Step 6. Merge web-fragment.xml files into the main web.xml            // file.            // 第六步.合并web-fragment.xml变成一个主要的web.xml            if (ok) {                ok = webXml.merge(orderedFragments);            }            // Step 7. Apply global defaults            // Have to merge defaults before JSP conversion since defaults            // provide JSP servlet definition.            // 第七步.应用全局的缺省设置            // 必须在JSP转换之前因为缺省的值提供了JSP servlet的定义            webXml.merge(defaults);            // Step 8. Convert explicitly mentioned jsps to servlets            // 第八步.转换明确提及的jsps到servlets            if (ok) {                convertJsps(webXml);            }            // Step 9. Apply merged web.xml to Context            // 第九步.应用碎片的web.xml到这个context            if (ok) {                configureContext(webXml);/* 创建了wrapper */            }        } else {            webXml.merge(defaults);            convertJsps(webXml);            configureContext(webXml);        }        if (context.getLogEffectiveWebXml()) {            log.info("web.xml:\n" + webXml.toXml());        }        // Always need to look for static resources        // Step 10. Look for static resources packaged in JARs        // 第十步 查找一些静态的资源包在JARs里面        if (ok) {            // Spec does not define an order.            // Use ordered JARs followed by remaining JARs            Set<WebXml> resourceJars = new LinkedHashSet<>();            for (WebXml fragment : orderedFragments) {                resourceJars.add(fragment);            }            for (WebXml fragment : fragments.values()) {                if (!resourceJars.contains(fragment)) {                    resourceJars.add(fragment);                }            }            processResourceJARs(resourceJars);            // See also StandardContext.resourcesStart() for            // WEB-INF/classes/META-INF/resources configuration        }        // Step 11. Apply the ServletContainerInitializer config to the        // context        // 第十一步. 应用ServletContainerInitializer配置给这个context        if (ok) {            for (Map.Entry<ServletContainerInitializer, Set<Class<?>>> entry : initializerClassMap                    .entrySet()) {                if (entry.getValue().isEmpty()) {                    context.addServletContainerInitializer(entry.getKey(), null);                } else {                    context.addServletContainerInitializer(entry.getKey(),                            entry.getValue());                }            }        }    }

1.解析xml文件
2.创建wrapper,并调用addchild方法作为Context的子容器,
这样就可以loadonstartup时调用load方法。加载standardWrapper。
Tomcat8.5源码-StandardWrapper

原创粉丝点击