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
阅读全文
0 0
- Tomcat8.5源码分析-ContextConfig
- Tomcat8.5源码分析-StandardHost
- Tomcat8.5源码分析-HostConfig
- Tomcat8.5源码分析-StandardContext
- Tomcat8.5源码分析-StandardWrapper
- tomcat8关键性源码分析
- Tomcat8源码分析(一)
- Tomcat8源码分析(二)
- Tomcat8源码分析(三)
- Tomcat8源码分析(四)
- tomcat8源码分析(一):导入eclipse
- tomcat8源码导入
- Eclipse运行Tomcat8源码
- Tomcat8.0.0源码研读
- tomcat8 源码 导入eclipse
- Tomcat8.5.11源码导入Myeclipse
- tomcat8.5.15源码编译运行
- tomcat8源码之架构解析
- Android攻城狮的第二门课(第3季)第2章 数据存储之SQLite
- rapidjson简单使用
- fzu-2266
- 精通MongoDB-索引与查询优化
- tensorflow运维(3):tensorflow1.0的一个bug:can't open CUDA library libcupti.so.8.0
- Tomcat8.5源码分析-ContextConfig
- php中curl模拟post提交多维数组
- 对话框
- web测试方法总结(二)
- 深入研究Spring-IoC :容器创建的几种方式
- 用git管理你的代码
- Unicode scalar value
- Linux下部署 jar包
- 如何用万用表检测电路