以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的?

Tomcat部署webapps下项目方法位于:HostConfig#deployApps,别问怎么知道的,看源码,也可以支持看下我前面的博客,虽然介绍粗枝大叶,但是也能走到这步了。

介绍下deployApps,最开始获取两个配置,分别是catalina-home/webapps以及catalina-home/conf/Catalina/localhost路径,filterAppPaths方法呢主要是过滤webapps下不想部署的项目,比如你有些大项目以前部署的,现在不想用了,但是不想删除呢?就可以忽略部署来节省Tomcat启动时间,具体方式就是在server.xml中Host元素里添加属性deployIgnore,支持正则表达式过滤。

deployDescriptors、deployWARs是部署特定类型的项目,比如war包等,这里主要介绍的是deployDirectories,有兴趣的可以自行研究另外两种.

那我们明白了Tomcat部署项目还是得靠deployDirectories方法.

HostConfig#deployDirectories方法如下,思路清晰,先介绍个大体,webapps下每个项目,只要是文件夹的(名字不为META-INF\WEB-INF)的,都会通过多线程的方式去”部署项目”,(这里需要提及一点,怕引起误会,这里Tomcat默认给配置的ExecutorService初始线程个数、最大线程个数都是1,这个就尴尬了,是啥原因引起的无从而就,如果调大个数是否能提高销量有待确认!)下面开始一点点介绍这个“部署”过程.

第一步,介绍ContextName实例化

name是webapps下各个文件夹类项目的名字,FWD_SLASH_REPLACEMENT就是 # ,VERSION_MARKER就是 ## , 代码比较简单,直接看结果,比如webapps下doc目录,最后得到的四个属性值结果就是 baseName就是docs ,version就是 “”,path就是 /docs ,name就是 /docs , 其他正常项目名不含#都是类似,举两个个例:Root目录,baseName是Root,version就是“” , path就是 “”, name就是 “”  .

第二步.线程来调用DeployDirectory完成部署

DeployDirectory是HostConfig内部类,实现了Runnable,持有三重要属性:HostConfig--外部类实例,ContextName--上面初始化的上下文名称类,File---当前webapps下目录的File句柄

run方法是核心,一看还不是调用HostConfig#deployDirectory!

第三步. HostConfig#deployDirectory部署项目

代码比较长,分成片段来记录:  前几行打印日志,就是Tomcat常见到的日志如下.  然后  xml文件引用指向 webapps下当前正在部署的项目(暂叫A吧),xml指向A项目META-INF/content.xml文件,而xmlCopy指向 catalina-home/conf/Catalina/localhost/A.xml,copyThisXml默认是false,deployThisXML默认是true.

Deploying web application directory E:\Tomcat_Source_Code\apache-tomcat-8.0.53-src\catalina-home\webapps\docs

代码片段二. 截取了try-catch块前半段, 由于deployThisXML默认是true,但是我们假设content.xml不存在的情况,就会执行if判断逻辑最后一段,contextClass默认是StandardContext,所以实例化了一个StandardContext!

代码片段三. try-catch块后半段逻辑:configClass默认是ContextConfig,是个Tomcat的监听器,实例化后在StandardContext上监听着,此外StandardContext赋值四个ContextName的属性.

然后将StandardContext和StandardHost关联起来!  代码片段四.finally块做了一些收尾工作,这个留待时候再分析,先分析StandardContext与StandardHost的关联!

StandardHost和StandardContext关联起来步骤比较复杂!

先判断是否webapps是否有项目名解析之后name一样的,抛出异常来不允许这样做!将StandardContext父类设置为StandardHost,将StandardContext作为value,项目名name作为key存入StandardHost的 children属性中(这也说明StandardHost的getChildren肯定是调用children.values()来获取);   部署一个项目之后就会调用项目StandardContext#start方法,项目启动之后触发对应监听事件.  StandardContext#start简单分析见这里,Tomcat8源码笔记(九)组件StandardContext启动流程--未完待续

代码片段四.finally块

部署完成之后,最终达成这样的效果,将部署信息存放在HostConfig的deployed中,比如 /docs--对应部署信息.

大体流程粗糙的写了一遍,具体细节,类我还需要熟悉在记录吧。

 

 

Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目的更多相关文章

  1. Tomcat8源码笔记(三)Catalina加载过程

    之前介绍过 Catalina加载过程是Bootstrap的load调用的  Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...

  2. Tomcat8源码笔记(七)组件启动Server Service Engine Host启动

    一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...

  3. Tomcat8源码笔记(六)连接器Connector分析

    根据 Tomcat8源码笔记(五)组件Container分析 前文分析,StandardService的初始化重心由 StandardEngine转移到了Connector的初始化,本篇记录下Conn ...

  4. Tomcat8源码笔记(五)组件Container分析

    Tomcat8源码笔记(四)Server和Service初始化 介绍过Tomcat中Service的初始化 最先初始化就是Container,而Container初始化过程是咋样的? 说到Contai ...

  5. Tomcat8源码笔记(四)Server和Service初始化

    上一章 简单说明下Tomcat各个组件: Server:服务器,Tomcat服务器,一个Tomcat只有一个Server组件; Service:业务层,是Server下最大的子容器,一个Server可 ...

  6. Tomcat8源码笔记(一)Lifecycle接口

    第一次阅读Tomcat8源码,就以Lifecycle作为笔记阅读的开篇吧,一千个读者就有一千个哈姆雷特,每个人都Tomcat的理解都不同,如果不记录一次Tomcat源码可能忘了就忘了. 断断DEBUG ...

  7. Tomcat8源码笔记(九)组件StandardContext启动流程--未完待续

    StandardContext代表的是webapps下项目,一个项目就是一个StandardContext,作为Tomcat组件的一部分,就会实现Lifecycle接口,被Tomcat管理着生命周期, ...

  8. Tomcat8源码笔记(二)Bootstrap启动

    TOMCAT源码调试入口是Bootstrap类的main方法,我的启动参数VM: -Dcatalina.home=E:/Tomcat_Source_Code/apache-tomcat-8.0.53- ...

  9. Tomcat8源码编译及导入Eclipse中研究

    最近因为需求需要修改Tomcat中的某些功能,无奈只能研究那部分源码然后稍作修改. 目前Tomcat最新版是8.0,下载了源码包,编译并导入Eclipse中研究比较方便. 1. Tomcat8源码编译 ...

随机推荐

  1. fortran常用语句--读写带注释文档、动态数组等语法

    1.判断读取文档有多少行数据(文档最后的空行不计入其中): 首先在变量定义区域下方和执行语句前声明在程序中要被调用的GetFileN函数: external GetFileN 接下来在函数外部后边写上 ...

  2. JavaScript-BOM与DOM

    BOM与DOM BOM: Browser Object Model(浏览器对象模型),即把 浏览器 当做一个对象来看待.BOM 除了可以访问文档中的组件之外,还可以访问 浏览器组件,比如页面中的 na ...

  3. DataTransfer对象的一些总结

    所有元素都支持防止目标事件,但是这些元素默认是不允许释放的,如果拖动元素经过不允许放置的元素无论用户如何操作,都不会触发drop事件,不过可以把任何元素变成有效的放置目标.方法是重写dropenter ...

  4. WBS分析

    我们的产品是2048是一个基于安卓平台开发的小游戏,WBS如下: 进一步优化版本: 小组最终版本:

  5. 下划线“_”在oracle中不是单纯的表示下划线的意思,而是表示匹配单一任何字符!

    [解决办法]1.使用 escape() 函数escape关键字经常用于使某些特殊字符,如通配符:'%','_'转义为它们原来的字符的意义,被定义的转义字符通常使用'\',但是也可以使用其他的符号.例如 ...

  6. C++输出格式

    C++输出格式 C++中默认输出有效位数是6位,即 则输出: 221.111.11011199967 //6位有效数字,自动截取保存六位1.99967e+006 //六位以上且无法省略显示将会变为指数 ...

  7. Django积木块九——富文本编辑器

    富文本编辑器 前端和后端都可以用富文本编辑器 # pip install django-tinymce # setting 'tinymce' TINYMCE_DEFAULT_CONFIG = { ' ...

  8. Hadoop2.0源码包简介

    Hadoop2.0源码包简介 1.解压源码包: 2.目录结构: hadoop-common-project:Hadoop基础库所在目录,如RPC.Metrics.Counter等.包含了其它所有模块可 ...

  9. WEB站点服务器安全配置

    WEB站点服务器安全配置   本文转自:i春秋社区   // 概述 // 熟悉网站程序 // 更改默认设置的必要性 // 目录分析与权限设置技巧 // 防止攻击其他要素 // 公司官网不可忽视的安全性 ...

  10. 微信小程序合法域名配置-不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书

    微信小程序合法域名配置-不校验合法域名.web-view(业务域名).TLS 版本以及 HTTPS 证书 很多教程说按照以上方式调用即可.但是当我们在程序中实际调用以上程序时,就会报错, http:/ ...