快精灵印艺坊 您身边的文印专家
广州名片 深圳名片 会员卡 贵宾卡 印刷 设计教程
产品展示 在线订购 会员中心 产品模板 设计指南 在线编辑
 首页 名片设计   CorelDRAW   Illustrator   AuotoCAD   Painter   其他软件   Photoshop   Fireworks   Flash  

 » 彩色名片
 » PVC卡
 » 彩色磁性卡
 » 彩页/画册
 » 个性印务
 » 彩色不干胶
 » 明信片
   » 明信片
   » 彩色书签
   » 门挂
 » 其他产品与服务
   » 创业锦囊
   » 办公用品
     » 信封、信纸
     » 便签纸、斜面纸砖
     » 无碳复印纸
   » 海报
   » 大篇幅印刷
     » KT板
     » 海报
     » 横幅

Tomcat研究之组件结构


Tomcat研究之组件结构








 


 



大家好,上篇介绍了《Tomcat研究之ClassLoader》,这篇我们介绍组件结构



     在没有任何实质性资料的前提下研究Tomcat的内核将是异常困难的事情,但无论如何还有opensource,我们至少可以跟踪Tomcat成百上千的类,为了我们能彻底解开Tomcat的面纱,我们还是要继承努力.



   通过UML类图不难看出,Core包里面最重要的一个类是ContainerBase,而这个抽象类实现了Container, Lifecycle, Pipeline, MBeanRegistration, Serializable接口, Serializable接口大家都已很认识,我们重在研究前几个接口,因为我们猜想整个Tomcat的部分构架可能是建立在这几个基础接口上.







    在进入分析之前我们先回忆一下config.xml(server.xml)文件,从这个文件及apache的文档我们大体可以了解到Tomcat宏观上是有下面几个部分组成:



-          Server  server元素是JVM的入口点,整个配置文件只有一个,因为server不是容器(container),因此不能嵌套子组件.server在某一指定的端口监听shutdown命令.server可以包含一个或多个service实。







-          Service service有共享同一个Container的一个或多个Connectors组成,一般Service就是一个Engine,但没有明确规范要求如此.因为Service不是一个Container,因此不能在里面嵌套子组件(比如Loggers/Valves)。







-          Connector connector就是一个Tomcat与客户端的连接,Tomcat有两种典型的Connector:http,JK2.http connector监听来自Browser的连接(通常在我们认识的8080端口),JK2.来自其他WebServer的哀求(默认在8009端口监听)。Connector会把获得的哀求交给Engine处理。







-          Engine Engine下可以配置多个虚拟主机Virtual Host,每个虚拟主机都有一个域名当Engine获得一个哀求时,它把该哀求匹配到某个Host上,然后把该哀求交给该Host来处理Engine有一个默认虚拟主机,当哀求无法匹配到任何一个Host上的时候,将交给该默认Host来处理







-          Host host代表一个虚拟主机,默认是localhost,host下可以部署多个web application,在我们实际应用中一般要考虑问题的对象就是host








 


 



1.         org.apache.catalina.Lifecycle







通用的组件声明周期接口,一般Tomcat的组件都要实现这个接口(但不是必须的),这个接口是为所有组件提供一样的start和stop。主要方式有:







//增加一个监听器







public void addLifecycleListener(LifecycleListener listener);








 


 



/**







*这个方式应该在任何public方式被调用前被调用







*该方式发送一个START_EVENT事件到所有注册到







*该组件的监听器







*/







public void start() throws LifecycleException;








 


 



/**







*这个方式应该在所有public方式被调用之后被调用







*该方式发送一个STOP_EVENT事件到所有注册到







*该组件的监听器







*/







public void stop() throws LifecycleException;








 


 



2.         org.apache.catalina. LifecycleListener







该接口用于监听一些重要事件(包括实现了Lifecycle接口组件产生的start,stop事件)







主要方式是:







//处理监听到的事件







public void lifecycleEvent(LifecycleEvent event);








 


 




 


 



3.         org.apache.catalina.Container







容器是用于从客户端取得哀求(request)并且处理哀求并回复给客户端(response)的对象。容器可以支持(可选)pipeline,以便能在运行时按配置的顺序处理哀求。







在Tomcat里面,容器在概念上存在以下及层:







Engine    哀求处理入口点,可以包含多个Host和Context







Host        代表一个虚拟主机







Context        代表单个ServletContext,可以包含多个Wrappers







Wrapper  代表单个Servlet,假如Servlet实现了SingleThreadModel,可以代表单个Servlet的多个实例。







容器为了实现自己的功能常常要绑定一些其他组件,这些组件的功能可能被共享,也可以被单独定制,下面是被使用的组件:







Loader       ClassLoader,装载Java Classes







Logger       实现了ServletContext的log方式,用于记录日志







Manager         治理与容器绑定的session池







Realm        用户安全治理







Resources  JNDI资源访问







主要的方式:








 


 



//增加容器监听器







public void addContainerListener(ContainerListener listener);








 


 



//增加property监听器







public void addPropertyChangeListener(PropertyChangeListener listener);








 


 



/**







*处理Request,并产生相应地Response







*param request 处理的哀求







*param  response 产生的response







*/







public void invoke(Request request, Response response)   throws IOException, ServletException;








 


 



4.         org.apache.catalina. ContainerListener







容器事件监听器,注重的是start,stop是正常的生命周期事件(LiftcycleEvent)不是容器事件。主要方式:








 


 



//处理容器事件







public void containerEvent(ContainerEvent event);







5.         org.apache.catalina. Pipeline







Pipleline是Valve的集合,当invoke方式被调用时,它会按指定的顺序调用Valve,它总是要求有一个Valve必须处理传递的request(一般是最后一个)并产生response,否则就把request传递到下一个Valve。







  一般一个容器仅绑定一个Pipleline实例,一般说来容器会把处理request的功能封装到一个容器绑定的Valve里(这个Valve应该在Pipleline最后被执行)。为了完成这个功能,Pipleline提供了setBasic()方式以保证Valve被最后执行,而其他Valve按顺序被调用。







6.         org.apache.catalina.Valve







     Valve是被绑定在一个Container上的哀求处理组件,一组Valve被按顺序绑定在一个Pipleline上。Valve最重要的一个方式是:








 


 



/**







 *一个Valve可能按照一定的顺序执行下面的动作







 *1.检查并且(或者)修改指定的Request和Response属性







 *2.检查Request属性,生成相应的Response并返回控制权到调用者







 *3.检查Request和Reponse属性,包装这些对象并增强它们的功能,然后把它们传







到下一个组件







     *4.假如相应的Response没有被产生(并且控制权也没有被返回)调用Pipleline







上的下一个Valve(假如有)通过方式context.invokeNext()







     *5.检查(但不修改)Response属性(调用后面的Valve或Container产生的)







     *Valve一定不能作下面的事情







     *1.改变Request的一些属性(Change request properties that have







        already been used to direct the flow of processing control







        for this request)







       *2.创建一个已经被创建并且已经被传递的Response







     *3.在调用invokeNext()方式并返回后修改包含Response的HTTP Header信息







     *4.在invokeNext()调用返回后在绑定Response上的输出流上作任何调用







     *@param request 将被处理的Request







     *@param response 将被创建的Response







     *@param context 被用来调用下一个Valve的Valve Context







      public void invoke(Request request, Response response,







                       ValveContext context)







        throws IOException, ServletException;







7.         org.apache.catalina.ValveContext







一个ValveContext是这样一种机制:一个Valve可以触发下一个Valve的调用,而不必知道机制的内在实现。







8.         org.apache.catalina.Engine







Engine是一个容器,是Cataline的Servlet的入口点。







当发布一个连接到Web Server的Cataline时可能不使用Engine,因为Connectior将使用Web Server的资源决定使用哪个Context处理Request。







附属于Engine的子容器根据Engine实现的不同可能是Host或Context(单个Servlet Context)。







假如使用了Engine,在Cataline的层次中它就是顶层容器,因此setParent()应改抛出IllegalArgumentException非常。从Engine下面几个方式我们可以看出其的结构:








 


 



/**







    * 设定Engine附属的Service







    * @param service The service that owns this Engine







    */







    public void setService(Service service);








 


 



    /**







     * Set the default hostname for this Engine.







     *







     * @param defaultHost The new default host







     */







    public void setDefaultHost(String defaultHost);








 


 



    /**







     * Set the DefaultContext







     * for new web applications.







     *







     * @param defaultContext The new DefaultContext







     */







    public void addDefaultContext(DefaultContext defaultContext);








 


 



9.         org.apache.catalina. Host







Host是一个容器,它代表一个虚拟主机。







当发布一个连接到Web Server的Cataline时可能不使用Host,因为Connectior将使用Web Server的资源决定使用哪个Context处理Request。







Host所附属的父容器通常是Engine,附属于Host的子容器通常是Context(单个Servlet Context)。







Host接口里面的方式多数都是关于修改Host属性及设定默认的Context。这里我们不再一一列举。







10.      org.apache.catalin. Context







      Context是一个容器,它代表一个ServletContext,一个Cataline Engline中的单个的Web Application。Context所附属的父容器是Host,附属于Context的子容器是Wrapper(代表单个Servlet)。Context接口里面多数是关于Web Application的设置的方式,我们可以参考Web.xml文件研究里面的方式,里面多数方式都是如何读取Web.xml文件里的资源。







11.      org.apache.catalina.Wrapper







Wrapper是一个容器,它代表单个Servlet。Wrapper治理Servlet的生命周期,包括调用init()和destory()方式。







Wrapper所附属的父容器是Context,没有附属于Wrapper的子容器,方式addChild()应该抛出IllegalArgumentException非常。







Wrapper接口里面的方式都是关于读取Servlet的属性,可以参考Web.xml文件里面关于<servlet>标签的定义。







12.  org.apache.catalina.Server







Server是整个Catalina容器的入口点,可以包含多个Service和顶层资源元素。一般说来实现Server接口的类也应该同时实现Lifecycle接口,当start()和stop()方式被调用的时候调用Service相应的方式。







   Server负责在指定的端口监听连接,当有连接被接受的时候,Server会分析哀求的第一行信息,假如是SHUTDOWN则stop服务。可以参考Server.xml文件关于Server的定义。







13.      org.apache.catalina. Service







       Service是一个或多个共享同以Container的Connectiors的集合。







   JVM可以包含一个或多个Service实例,但它们相互之间是完全独立的,它们仅共享JVM的资源。







14.  org.apache.catalina. Connector







      Connector是一个从客户端接受哀求(request)并生成回应(reponse)的组件。一个Connection通常执行下面的逻辑:







1)      从客户端程序接受哀求







2)      创建Request和Response,并把下面这些属性设置到这些对象







(1)对所有的Request,connector,protocol,protocol,response,scheme,secure,serverName,serverPort,serverPort属性必须被设置。contentLength,contentType通常也被设置。







3)      对所有的HttpRequests,method,queryString,requestedSessionCookie,requestedSessionId,requestedSessionURL,requestURI,secure属性必须被设置。另外所有addXxx方式也必须被调用以记录cookies,headers和locales信息。







4)      对所有的Responses属性connector,request,stream属性必须被设置。







对HttpResponses来说,connector不会为它设置额外headers信息。

1.         Tomcat整体架构类图


















 


 



下篇将从Tomcat的各个组件入手介绍Tomcat。




返回类别: 教程
上一教程: Java常见问题总结
下一教程: 给jikes指定encoding属性的编译过程

您可以阅读与"Tomcat研究之组件结构"相关的教程:
· Tomat组件研究之ThreadPool
· JVM之CLASS文件结构
· Structs深入研究(一)-----Struts framework的工作原理和组件
· RESIN/TOMCAT和MYSQL的连接解决方式
· WIN2000 SERVER IIS和TOMCAT5多站点配置
    微笑服务 优质保证 索取样品