Context实例表示一个具体的web应用程序,其中包含一个或者多个Wrapper实例,每个Wrapper表示一个具体的servlet定义。StandardContext类是Context接口的标准实现。

一、相关类 UML图:

1、StandardContext是一个相当复杂的容器类,他实现了Context接口,类的很多功能是依赖于其他对象完成的,因此在start启动Context时会启动所有的这些依赖对象,Available变量表示StandardContext对象是否可用,如果启动都正常且配置文件读取正常,则Available变量为True,如果启动失败则为False;启动时会给Context的所有监听器发送START_EVENT事件,ContextConfig对象也是其中一个监听器,他会读取web.xml文件并初始化配置,如果成功则设置Configured变量为True,否则设置为False;

2、每个容器对象都有name属性,StandardContext对象也不例外,也有name属性;DocBase表示该web应用的路径,该应用下的所有servlet都是该路径加上servlet的路径组合而来;welcomeFiles存储了默认首页的名称列表;

3、每个Context应用都有若干个servlet,children变量是一个hashMap类型的,存储了所有servlet实例Wrapper对象,存储时是以Wrapper.Name和Wrapper对象为键值对存储的;

4、servletMappings是一个HashMap类型的变量,存储了servletPath和servletName的键值对关系,addServletMapping函数实现了将servletPath和servletName添加为一个映射的功能;

5、客户端的请求Request到达StandardContextValve.invoke方法时会调用Context.map方法查找到处理该请求的servlet对象,而这个map方法就是依赖StandardContextMapper对象完成的,StandardContextMapper.map方法会首先从Request请求中解析出relativeURI,然后拿这个路径到servletMappings去查找映射,根据映射关系中的servletName可以查找到对应的Wrapper对象;

6、WebAppLoader实现了Context的加载器,NamingContextListener实现了对StandardContext的监听,完成在Context启动和关闭时绑定对象到JDNI和从JDNI上解除绑定;

7、ProxyDirContext对象实现了DirContext接口,代理了对WARDirContext或者FileDirContext对象的访问,同时提供了缓存机制,其意义表示对web应用程序的war文件或者目录资源的访问控制和属性的访问控制;

8、StandardManager对象实现了Context中的session管理机制;charsetMapper对象实现了字符集映射器;Logger对象实现了Context的日志管理功能;Cluster对象实现了集群管理功能;realm对象实现了安全管理功能;resources对象实现了资源管理功能;pipeline对象实现了Context的管道功能,对Context.invoke调用都会转为对pipeline.invoke调用;

9、ContextConfig对象也是作为Context的一个监听器之一,代码如下:

因此在他的lifecycleEvent中的START_EVENT事件时会读取tomcat目录下Conf/web.xml文件和web应用目录下的WEB-INF/web.xml文件:

同时判断当前链接如果是安全链接https,则会添加许可阀到管道对象中:

此外还会安装一个验证器阀到管道对象中(根据配置文件中指定的web应用的验证方式(Basic, Form, Degister, Client-cert)来安装不同的验证器阀):

最后start方法如果成功读取和初始化配置文件并且成功的安装了相关阀门到管道对象,则设置Context的Configured变量为True,否则设置为False;

二、启动流程:

三、客户端请求处理流程:

1、客户端的请求通过在Connect里面生成Request和Response对象后,调用容器(Context)的invoke方法并传入request和response参数;

2、Context的invoke方法调用管道对象PipeLine的invoke方法,PipeLine.invoke又通过ValveContext调用到StandardContextValve.invoke方法,然后这个invoke方法通过协议方式(http)在Context里面查找到对应的Mapper对象,调用mapper.map方法来返回对应的Wrapper对象;

3、在StandardContextMapper.map方法里面,首先从request里面解析出requestURI和relativeURI,根据relativeURI在Context的servletMappings里面查找到对应的servetName(servletMappings里面存储了servletName和路径的映射关系),然后再拿servletName在children里面查找对应的servlet对象Wrapper(children是一个存储了servletName和Wrapper对象映射关系的HashMap);

4、在StandardContextMapper.map返回了对应的Wrapper对象后,最后调用Wrapper对象的invoke方法完成对servlet的调用;

那么Context中的servletName和servletPath是如何建立映射关系的了:

1、首先我们在应用程序的web.xml文件中配置了映射关系:

2、在webRuleSet.java文件中读取servlet-mapping的内容并调用Context. addServletMapping方法:

3、在Context.addServletMapping方法中将servletName和servletPath添加到servletMappings的hashMap变量中:

四、reLoad机制:

Context的reLoad机制是通过WebAppLoader类来实现的;

1、在WebAppLoader.setContainer里面调用setReloadable来设置WebAppLoader的reloadable变量,通过根据reloadable变量值为true或者false来开启或者停止线程;

2、由于WebAppLoader类实现了Runnable接口,因此可以启动一个线程来执行WebAppLoader.run方法;

3、WebAppLoader.run方法会调用classLoader.modified()来检查web应用下的文件有无变更,如果有则重新开启一个线程来执行Context.Reload方法;

4、Context.reload方法与start方法先将Context相关联的对象和子容器对象停止(stop),然后再开启(start);

五、JNDI配置:

1、配置:

在Context.xml文件中配置如下:

<Context>

<Resource name=”jdbc/xx” auth=”container” type=”javax.sql.DataSource”
password=”mysql” driverClassName=”com.mysql.jdbc.Driver” username=”root” url=”jdbc://mysql://127.0.0.1/xx”
/>

</Context>

那么在java代码中可以这样访问上面的服务:

InitialContext ctx = new InitialContext();

DataSource ds = (DataSource)ctx.lookup(“java:comp/env/jdbc/xx”);

2、那么Jdbc/xx 服务是如何绑定到JNDI上面的了:

  • 首先StandardContext.start方法会创建NamingContextListener对象,这个对象是一个绑定到StandardContext的监听器对象;
  • 然后StandardContext会发出START_EVENT事件消息,NamingContextListener接收到该事件后就创建NamingContext对象,并将此对象绑定在容器中:

  • 接着在createNamingContext函数中创建子上下文:

  • 一旦创建了子上下文,就会被已经由degister解析出来的ContextResource对象加载到上下文中

对于上面的配置信息,这里会依次创建jdbc子上下文和xx子上下文;

tomcat源码阅读之StandardContext的更多相关文章

  1. Tomcat源码阅读(二)初始化

    近来,我开始阅读tomcat的源码,感觉还挺清晰易懂:为了方便理解,我参考了网上的一些文章,把tomcat的组成归纳一下:整个tomcat的组成如下图所示: Tomcat在接收到用户请求时,将会通过以 ...

  2. tomcat源码阅读之载入器(Loader)

    一.Java类的载入器: 双亲委派模型: 1.JVM提供了三种类型的类加载器:引导类载入器(bootstrap class loader).扩展类载入器(extension class loader) ...

  3. tomcat源码阅读

    1      工具准备 需要SVN.Maven.JDK.Eclipse.Eclipse M2插件 2      下载源码及发布包 源码在这里:http://svn.apache.org/repos/a ...

  4. tomcat源码阅读之过滤器

    一.Servlet过滤器: 1.介绍: Servlet过滤器本身并不生成请求和响应对象,它只提供过滤作用. Servlet过滤器能够在Servlet被调用之前检查Request对象,修改Request ...

  5. tomcat源码阅读之SingleThreadModel

    一.接口简介: 实现了SingleThreadModel接口的servlet类只能保证在同一时刻,只有一个线程执行该servlet实例的service方法,在tomcat实现中会创建多个servlet ...

  6. tomcat源码阅读之安全机制

    一.领域(Realm): 1.Principal接口代表角色信息,包含了三个成员:用户名.密码.role列表(以逗号分隔),对应了tomcat-users.xml文件中一行user信息: Generi ...

  7. tomcat源码阅读之BackupManager

    一. 配置: <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOpti ...

  8. tomcat源码阅读之部署器

    我们知道web应用是用Context实例表示的,而Context是部署到Host实例中的,因此tomcat的部署器是关联的Host实例.Context实例可以用WAR文件部署,也可以把整个web应用的 ...

  9. tomcat源码阅读之集群

    一. 配置: 在tomcat目录下的conf/Server.xml配置文件中增加如下配置: <!-- Cluster(集群,族) 节点,如果你要配置tomcat集群,则需要使用此节点. clas ...

随机推荐

  1. 『PyTorch』第十一弹_torch.optim优化器

    一.简化前馈网络LeNet import torch as t class LeNet(t.nn.Module): def __init__(self): super(LeNet, self).__i ...

  2. Python多线程多进程

    一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...

  3. jenkins插件--Cobertura,JaCoCo,Emma-----(二)

    代码覆盖API插件 Jenkins中有许多代码覆盖插件:Cobertura,JaCoCo,Emma等等.这些插件的问题在于它们每个都自己实现了所有代码覆盖功能.因此,您可以获得不同的功能集,UI,CL ...

  4. Hibernate优化策略

    https://blog.csdn.net/blueheart20/article/details/21019043 https://blog.csdn.net/yerenyuan_pku/artic ...

  5. 微信小程序绑定数据(微信小程序交流群:604788754)

    在小程序开发中,用js绑定数据时,明明没报错,但页面没有显示绑定的数据内容.这有可能是相对应的js绑定数据的一些变量名字的问题.遇到这种情况.可以从新建立一个新的demo页面.把问题页面相对应的js. ...

  6. Cetus

    转自:https://github.com/Lede-Inc/cetus Cetus 简介 Cetus是由C语言开发的关系型数据库MySQL的中间件,主要提供了一个全面的数据库访问代理功能.Cetus ...

  7. 返回值为record类型的函 初始化 内存泄漏 复制

    1.函数需要初始化,否则下次调用函数时,Result还是上次的值,可能会引起误判.但是不会有内存泄漏,即使包含string类型的成员. 2.如果record包含的都是值类型的成员,比如integer, ...

  8. CodeIgniter $this->db->where()的自定义语句写法问题

    .自定义字符串:你可以手动的编写子句:$where = "name='Joe' AND status='boss' OR status='active'"; $this->d ...

  9. Python3 urllib抓取指定URL的内容

    最近在研究Python,熟悉了一些基本语法和模块的使用:现在打算研究一下Python爬虫.学习主要是通过别人的博客和自己下载的一下文档进行的,自己也写一下博客作为记录学习自己过程吧.Python代码写 ...

  10. 配置total commander 显示所有或特定文件夹 (带点的文件夹)

    在配置|忽略列表 下可以添加或删除需要隐藏的文件夹通配符.