当前位置:web 服务器 > Tomcat >>

Tomcat源码分析(三)--连接器是如何与容器关联的?

这篇文章要弄懂一个问题,我们知道,一个链接器是跟一个容器关联的,容器跟链接器是在什么时候关联上的?
  在明白这个问题前要先了解一下Digester库,这个库简单的说就是解析xml文件,这里有两个概念:模式和规则,所谓模式就是一个xml的标签,规则就是遇到一个xml标签需要做什么,看一下他主要的三个方法:
      1:addObjectCreate(String pattern, String className, String attributeName)    根据模式pattern实例化一个对象className
      2:addSetProperties(String pattern)   设置这个模式的属性
      3:addSetNext(String pattern, String methodName, String paramType)  添加模式之间的关系,调用父模式的
    上面可能不好理解,看tomcat是怎么用到Digester的,在org.apache.catalina.startup.Catalina.createStartDigester()的方法里(这个方法是在服务组件启动的时候调用的,详细参考Tomcat源码分析(一)--服务启动),在这个方法里有使用Digester来解析server.xml文件:
   
[java] 
digester.addObjectCreate("Server/Service", 
                                "org.apache.catalina.core.StandardService", 
                                "className");// 添加一个模式“Server/Service”,当在xml文件(这里是server.xml)里遇到“Server”标签下的Service标签的时候,根据标签Service的属性“className”为类名实例化一个对象,默认类名是"org.apache.catalina.core.StandardServer" 
       digester.addSetProperties("Server/Service"); //设置对象StandardService的属性,有些什么属性由xml里的Service标签指定 
       digester.addSetNext("Server/Service", 
                           "addService", 
                           "org.apache.catalina.Service");//调用Service标签的上一级标签Server的对象(即StandardServer)的addService方法,把Service添加进Server,设置它们的关系,最后一个参数表示addService方法的参数类型 
这样StandardServer和StandardService便有了所属关系,现在看容器跟链接器是怎么连接的,再看createStartDigester方法:
[java] 
digester.addObjectCreate("Server/Service/Connector", 
                                 "org.apache.catalina.connector.http.HttpConnector", 
                                 "className"); 
        digester.addSetProperties("Server/Service/Connector"); 
        digester.addSetNext("Server/Service/Connector", 
                            "addConnector", 
                            "org.apache.catalina.Connector"); 

这里很好理解,跟上面的是一样的,遇到标签Server/Service/Connector的时候(这里简化了说法,应该是标签Server下的子标签Service的子标签Connector,有点拗口),实例化HttpConnector,然后在它的上一级父容器StandardService下调用addConnector,这样就把链接器HttpConnector添加进容器StandardService下了,看StandardService的addConnector方法:
[java] 
public void addConnector(Connector connector) { 
     synchronized (connectors) { 
         connector.setContainer(this.container); //本来这里就应该把容器和连接器关联上的,但是在一开始tomcat启动的时候,Digester是先添加链接器,所以容器container还是为null的,但是没有关系,后面还会另一个地方关联他们,这里应该牢记的是容器和连接器都是在Service里面 
         connector.setService(this); 
         Connector results[] = new Connector[connectors.length + 1]; 
         System.arraycopy(connectors, 0, results, 0, connectors.length); 
         results[connectors.length] = connector; 
         connectors = results; 
 
         if (initialized) { 
             try { 
                 connector.initialize(); 
             } catch (LifecycleException e) { 
                 e.printStackTrace(System.err); 
             } 
         } 
 
         if (started && (connector instanceof Lifecycle)) { 
             try { 
                 ((Lifecycle) connector).start(); 
             } catch (LifecycleException e) { 
                 ; 
             } 
         } 
 
         // Report this property change to interested listeners 
         support.firePropertyChange("connector", null, connector); 
     } 
 
 } 
这个方法很简单,就是把一个链接器connector添加到StandardService的connectors数组里,然后关联上StandardService的容器。代码上也做了一点说明(很重要)。连接器添加进StandardService了,现在看容器是什么时候添加进StandardService的,其实方法是一样的,再回到createStartDigester方法:
[java] 
digester.addRuleSet(new EngineRuleSet("Server/Service/"));//这句代码是在createStartDigester方法里面 
--------------------------》下面进入EngineRuleSet类的addRuleInstances方法 
public void addRuleInstances(Digester digester) { 
       digester.addObjectCreate(prefix + "Engine", 
                                &quo

补充:软件开发 , Java ,
Apache
IIS
Nginx
Tomcat
如果你遇到web 服务器难题:
请访问www.zzzyk.com 试试
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,