您的位置:首页 > 运维架构 > Tomcat

探索《How Tomcat Works》心得(三)--容器

2016-05-18 19:06 429 查看
Tomcat第五章,讲述的是容器,如果抛开连接器,单独来看容器的话,理解起来的有点无味,所以这里我会结合第四章的连接器来谈谈我的心得。
Tomcat是个大工厂,而这个工厂要创造价值,并实现价值的输送与装换,就需要通道。so ,socket coming.
一个socket就是一个浏览器与一台服务器之间的通道,用来实现数据的输入与输出。基于上面所说的,tomcat使用 connector 和 container 两大模块来解决问题。connector用来处理socket,container用来处理请求响应数据。下面,我再累述一下tomcat的工作流程,这次我会加上容器的工作。
当connector启动的时候,他会组建处理器对象小组(存储HttpProcessor的Stock),让他们等着客户端的socket的到来。当浏览器发过来请求的socket,connector会从小组中叫来一个处理器对象(处理器对象),并且给他一个socket,让他自己去处理,自己等待下一个socket的到来。话说处理器(HttpProcessor)拿到socket之后,他会一直不断的循环的接受socket中的请求数据,并创建request和response两个人,创建之后就会教育他们,让他们知道自己的请求行,请求头等相关信息,response呢,把它教育成回信的快递,用于装载request中请求订单中的东西,他俩毕业之后,处理器并没有歇着,他是继续解析socket,一旦连接中又有请求过来,他就会教育出新的一批request和response。直到socket关闭,处理才下班休息。下面该看看request和response这哥俩的归宿了。它俩毕业之后,被HttpProcessor老师交给了它的老大connector小伙伴Container。要说connector和container是如何相识的,追述到tomcat启动的时候。
小猫会两眼一睁,就会创建connector,container,valve,Loader这四个同志。之后小猫就把container分配给connector,把loader,valve分配给container,然后才开始让connector工作。connector工作之后,才有了上面一段的内容。container作为connector的小伙伴,当然级别也不会低,它的角色不仅仅是容器,还是一根管道(Pipeline),之所以让它当一根管道,是为了方便控制,说道控制,阀门(valve)就来了,容器有一个基本阀门(通常用于加载servlet
class)和多个普通的阀门。容器在被创建的时候实例化了自己的Pipeline组件,这个组件用来管理它的多个阀门。Pipeline管理自身的阀门通过PipelineValueContext实现了一个机制。ValveContext最为Pipeline的内部类被实例化,因此,他可以自然的获得Pipeline的所有的阀门。ValveContext中有一个非常重要的方法,invokeNext();这个方法用于实际操作阀门。ValveContext还有一个重要的变量
subscript(下标),用于有序的处理valve数组。 每处理一个valve,subscript就会加1 。而invokeNext处理valve会调用valve的invoke方法,这个方法在执行处理之前会首先调用传进来的ValveContext的invokeNext方法,so ,形成递归,会执行完pipeline中的valve,但是根据它的机制,执行的先后顺序是倒序进行的。下面,分享下这段代码



下面是valve的一个实例的invoke方法:



当阀门执行basic阀门的时候,会加将request,response传到 servlet的service方法中。算是完成使命了。
在上面的介绍中,好像是把request和response哥俩忘记了,补充一下,connector把request和response传递给 container的invoke方法,container接下把request和response传给组件Pipeline的invoke方法,而Pipeline会调用自身内部类ValveContext的实例,按照上面介绍的机制,将request和response传递至每个valve,根据他们的需求跟那哥俩玩耍。其中,request和response会遇到basic阀门,它会根据request上的信息把他俩传递给对应servlet的service方法,到这,是我们servlet程序员拿到的request、response
对象了。
在本章开头书中介绍了不种类型的容器,书中介绍的很好理解,我就不进行累述了。在本章末尾,又介绍了context容器的应用。它包含两个wrapper容器。我做一下简单的介绍。
context涉及到多个wrapper,在启动服务的时候,他会创建多个wrapper,和一个context,和mapper,mapper就是为了管理wrapper的,所以他会把wrapper加到mapper中,再把mapper放到到context容器中。
当connector传过来的context容器的invoke中后,这个容器会像上面一样,一次执行阀门,到执行到基本阀门之时,他会根据请求的uri来取对应的wrapper,再把request和response放到wrapper的invoke,然后走上面的各个阀门的流程,走到basic 阀门,把request和response传到servlet的service方法中。
根据请求获取wrapper



context中Children是个map数组。
这是上面调用的根据请求路径获取wrapper的名字



这个东西是在启动服务的时候塞得:

context.addServletMapping("/Primitive", "Primitive");
context.addServletMapping("/Modern", "Modern");
上面映射的,前面是请求相对路径,后边是容器名字。

好,就到这里了,书上有好多的UML图,希望能更好的帮助我们理解各种对象的关系。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: