查看tomcat启动文件都干点啥---server对象

系统 1805 0

     在上一章 查看tomcat启动文件都干点啥---Catalina.java 中说道了构造Server,,这次尝试着说一下Tomcat中Server的内容,首先看一下org.apache.catalina.Server接口中定义的方法:

查看tomcat启动文件都干点啥---server对象

  从这里至少可以看出Server中包含很多Service,通过实现如下接口添加一个新的Service到Services的集合中,或者从集合中删除指定的Service:  

      
        public
      
      
        void
      
      
         addService(Service service);


      
      
        public
      
      
        void
      
       removeService(Service service);
    

  通过实现如下接口来完成通过service的名称返回Service的操作:  

      
        public
      
       Service findService(String name);
    

  通过实现如下接口来完成获取返回Server中所有Service的操作:  

      
        public
      
       Service[] findServices();
    

  对于Server的网络内容的设置和获取通过如下方法,包括设置地址,端口:  

      
        public
      
      
        int
      
      
         getPort();


      
      
        public
      
      
        void
      
       setPort(
      
        int
      
      
         port);


      
      
        public
      
      
         String getAddress();


      
      
        public
      
      
        void
      
       setAddress(String address);
    

  获取和指定shotdown命令:

      
        public
      
      
         String getShutdown();


      
      
        public
      
      
        void
      
       setShutdown(String shutdown);
    

  获取和设置父类的加载器:  

      
        public
      
      
         ClassLoader getParentClassLoader();


      
      
        public
      
      
        void
      
       setParentClassLoader(ClassLoader parent);
    

  如果设置了Catalina,那么也提供获取和设置的方法:  

      
        public
      
      
         Catalina getCatalina();


      
      
        public
      
      
        void
      
       setCatalina(Catalina catalina);
    

  通过Server接口至少我们能够得出结论:Server中包含多个Service对象。

  结构如下:

查看tomcat启动文件都干点啥---server对象

  值得注意的是Server借口继承了Lifecycle接口,

      
        public
      
      
        interface
      
       Server 
      
        extends
      
       Lifecycle 
    

  Lifecycle 接口就是来控制Server极其组件的生命周期的,组件实现Lifecycle借口,就可以提供一致化的机制来启动和停止组件。下面看一下 Lifecycle的内容:

  首先是一些常量列表,小插曲,在Tomcat7.0.53中,tomcat在此处的注释有小问题,有兴趣的人可以看一下。  

      
        //
      
      
        组件初始化之前的事件
      
      
        public
      
      
        static
      
      
        final
      
       String BEFORE_INIT_EVENT = "before_init"
      
        ;

   
      
      
        //
      
      
        组件初始化之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String AFTER_INIT_EVENT = "after_init"
      
        ;

   
      
      
        //
      
      
        组件start的事件
      
      
        public
      
      
        static
      
      
        final
      
       String START_EVENT = "start"
      
        ;

   
      
      
        //
      
      
        组件start之前的事件
      
      
        public
      
      
        static
      
      
        final
      
       String BEFORE_START_EVENT = "before_start"
      
        ;

   
      
      
        //
      
      
        组件start之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String AFTER_START_EVENT = "after_start"
      
        ;

   
      
      
        //
      
      
        组件stop之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String STOP_EVENT = "stop"
      
        ;

   
      
      
        //
      
      
        组件stop之前的事件
      
      
        public
      
      
        static
      
      
        final
      
       String BEFORE_STOP_EVENT = "before_stop"
      
        ;

   
      
      
        //
      
      
        组件stop之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String AFTER_STOP_EVENT = "after_stop"
      
        ;

   
      
      
        //
      
      
        组件destrop之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String AFTER_DESTROY_EVENT = "after_destroy"
      
        ;

   
      
      
        //
      
      
        组件destrop之前的事件
      
      
        public
      
      
        static
      
      
        final
      
       String BEFORE_DESTROY_EVENT = "before_destroy"
      
        ;

    
      
      
        //
      
      
        组件periodic的事件 
      
      
        public
      
      
        static
      
      
        final
      
       String PERIODIC_EVENT = "periodic";
    

  下面就是Lifecycle接口定义的方法列表:

查看tomcat启动文件都干点啥---server对象

  既然Server中包含的主要对象就是Service,实现了Service就是对外提供服务了,下面在看一下Service的接口定义:

查看tomcat启动文件都干点啥---server对象

  看了定义的方法之后,很想逐一说明一下,可能会发现问题:

  在Service中添加或移除connector的方法:    

      
        public
      
      
        void
      
      
         addConnector(Connector connector);


      
      
        public
      
      
        void
      
       removeConnector(Connector connector);
    

    说明在每个Service中有多个Connector。

  在Service中添加或移除Executor的方法:   

      
        public
      
      
        void
      
      
         addExecutor(Executor ex);


      
      
        public
      
      
        void
      
       removeExecutor(Executor ex);
    

  返回所有Connector的方法:

      
        public
      
       Connector[] findConnectors();
    

  返回所有executor的方法:  

      
        public
      
       Executor[] findExecutors();
    

  设置和获取Container的方法:  

      
        public
      
      
         Container getContainer();


      
      
        public
      
      
        void
      
       setContainer(Container container);
    

  获取和设置关联的Server对象的方法:  

      
        public
      
      
        void
      
      
         setServer(Server server);


      
      
        public
      
       Server getServer();
    

  给Service设置获取名称的方法:  

      
        public
      
      
        void
      
      
         setName(String name);


      
      
        public
      
       String getName();
    

  以上就是Service接口定义的主要方法,得出在Service中包含一个或多个Connector,包含一个或多个Executors和一个Container对象。接着上面的Server---Service图我们可以得出如下关系图:                      

            |---------Connector 

 Server----Service----|

             |----------Container

查看tomcat启动文件都干点啥---server对象

  由此可知在Tomcat中的两个重要的组件就是Connector和Container。下面我们着重看一下Connector和Container。

  Container的主要功能是执行从客户端接收的请求,然后给出回应。看一下Container接口定义的方法:

  添加,删除和获取一个子Container:  

      
        public
      
      
        void
      
      
         addChild(Container child);


      
      
        public
      
      
        void
      
      
         removeChild(Container child);


      
      
        public
      
      
         Container findChild(String name);


      
      
        public
      
       Container[] findChildren();
    

  对应的在Container中就应该有设置和获取父Container的方法:  

      
        public
      
      
        void
      
      
         setParent(Container container);


      
      
        public
      
       Container getParent();
    

  在Container中添加,移除和获取事件监听器:

      
        public
      
      
        void
      
      
         addContainerListener(ContainerListener listener);


      
      
        public
      
      
        void
      
      
         removeContainerListener(ContainerListener listener);


      
      
        public
      
       ContainerListener[] findContainerListeners();
    

  在Container中添加,移除和获取属性变更监听器:  

      
        public
      
      
        void
      
      
         addPropertyChangeListener(PropertyChangeListener listener);


      
      
        public
      
      
        void
      
       removePropertyChangeListener(PropertyChangeListener listener);
    

  触发Container事件:

      
        public
      
      
        void
      
       fireContainerEvent(String type, Object data);
    

  记录指向这个container的请求与响应的日志:  

      
        public
      
       AccessLog getAccessLog();
    

  设置和获取作用在该container及其子container上的方法的延迟时间,单位秒:  

      
        public
      
      
        void
      
       setBackgroundProcessorDelay(
      
        int
      
      
         delay);


      
      
        public
      
      
        int
      
       getBackgroundProcessorDelay();
    

  设置和获取相关的集群:  

      
        public
      
      
        void
      
      
         setCluster(Cluster cluster);


      
      
        public
      
       Cluster getCluster();
    

  设置和获取Loadeer:  

      
        public
      
      
        void
      
      
         setLoader(Loader loader);


      
      
        public
      
       Loader getLoader();
    

  设置和获取负责管理该Container对应Session pool的Manager对象:  

      
        public
      
      
        void
      
      
         setManager(Manager manager);


      
      
        public
      
       Manager getManager();
    

  设置和获取Container的名字描述:  

      
        public
      
      
        void
      
      
         setName(String name);


      
      
        public
      
       String getName();
    

  设置和获取父类的ClassLoader:  

      
        public
      
      
        void
      
      
         setParentClassLoader(ClassLoader parent);


      
      
        public
      
       ClassLoader getParentClassLoader();
    

  获取Pipeline,负责管理该Container中的相关值:  

      
        public
      
       Pipeline getPipeline();
    

  设置和获取Container的上下文资源:  

      
        public
      
      
        void
      
      
         setResources(DirContext resources);


      
      
        public
      
       DirContext getResources();
    

  设置和获取启动和停止children container的线程数,可以并行的启动和停止子container:  

      
        public
      
      
        void
      
       setStartStopThreads(
      
        int
      
      
         startStopThreads);


      
      
        public
      
      
        int
      
       getStartStopThreads();
    

  Connector类中的变量已经方法实现如下:

  代表一个Container的入口的变量:  

      
        protected
      
       Adapter adapter = 
      
        null
      
      ;
    

  实现Servlet的API规则匹配的变量:  

      
        protected
      
       Mapper mapper = 
      
        new
      
       Mapper();
    

  是否允许Trace:  

      
        protected
      
      
        boolean
      
       allowTrace = 
      
        false
      
      ;
    

  异步请求的超时时间:  

      
        protected
      
      
        long
      
       asyncTimeout = 10000;
    

  是否允许DNS查找的标记:  

      
        protected
      
      
        boolean
      
       enableLookups = 
      
        false
      
      ;
    

  Mapper监听器:  

      
        protected
      
       MapperListener mapperListener = 
      
        new
      
       MapperListener(mapper, 
      
        this
      
      );
    

  GET和POST方法中,Container解析的最大的参数个数限制(默认值为1000,当设置数值小于0时,表示没有限制):  

      
        protected
      
      
        int
      
       maxParameterCount = 10000;
    

  Container接收POST方法传递的最大数据(默认值为2M):  

      
        protected
      
      
        int
      
       maxPostSize = 2 * 1024 * 1024;
    

  在Container认证时候默认保存的最大数据:(默认值4K):  

      
          protected
      
      
        int
      
       maxSavePostSize = 4 * 1024;
    

  一系列以逗号分割的,application/x-www-form-urlencoded形式的方法请求体,以什么方式转化成方法的集合:  

      
        protected
      
       String parseBodyMethods = "POST";
    

  通过parseBodyMethods方式确定的方法集合:  

      
        protected
      
       HashSet<String> parseBodyMethodsSet;
    

  监听请求端口的数量:(默认值为-1):  

      
        protected
      
      
        int
      
       port = -1;
    

  connector对象将请求重定向到那个Server:  

      
          protected
      
       String proxyName = 
      
        null
      
      ;
    

  connector对象请求重定向到server的哪个端口:  

      
        protected
      
      
        int
      
       proxyPort = 0;
    

   从no-ssl到ssl重定向端口:  

      
        protected
      
      
        int
      
       redirectPort = 443;
    

  通过connector接收到的所有请求的请求方案:  

      
          protected
      
       String scheme = "http";
    

  是否给每个接收到的请求设置安全连接标记:  

      
        protected
      
      
        boolean
      
       secure = 
      
        false
      
      ;
    

  一个String帮助对象:  

      
        protected
      
      
        static
      
      
        final
      
       StringManager sm =
      
         StringManager.getManager(Constants.Package);
      
    

  关联的Service对象:  

      
        protected
      
       Service service = 
      
        null
      
      ;
    

  URL编码:  

      
        protected
      
       String URIEncoding = 
      
        null
      
      ;
    

  是否用body编码给URL编码:(不明白)  

      
        protected
      
      
        boolean
      
       useBodyEncodingForURI = 
      
        false
      
      ;
    

  是否用IP绑定虚拟主机:  

      
        protected
      
      
        boolean
      
       useIPVHosts = 
      
        false
      
      ;
    

  下面看一下Connector的构造函数:

      
          public
      
      
         Connector() {

        
      
      
        this
      
      (
      
        null
      
      
        );

    }



    
      
      
        public
      
      
         Connector(String protocol) {

        setProtocol(protocol);

        
      
      
        //
      
      
         Instantiate protocol handler
      
      
        try
      
      
         {

            Class
      
      <?> clazz =
      
         Class.forName(protocolHandlerClassName);

            
      
      
        this
      
      .protocolHandler =
      
         (ProtocolHandler) clazz.newInstance();

        } 
      
      
        catch
      
      
         (Exception e) {

            log.error(sm.getString(

                    
      
      "coyoteConnector.protocolHandlerInstantiationFailed"
      
        ), e);

        }

    }
      
    
    
        Connector的构造函数中第一步是根据
    
    protocol名称HTTP/1.1,AJP/1.3或者protocol handler的类的全路径名称,下面是setProtocol方法的代码实现:  
  
        
          public
        
        
          void
        
        
           setProtocol(String protocol) {



        
        
        
          if
        
        
           (AprLifecycleListener.isAprAvailable()) {

            
        
        
          if
        
         ("HTTP/1.1"
        
          .equals(protocol)) {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.http11.Http11AprProtocol"
        
          );

            } 
        
        
          else
        
        
          if
        
         ("AJP/1.3"
        
          .equals(protocol)) {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.ajp.AjpAprProtocol"
        
          );

            } 
        
        
          else
        
        
          if
        
         (protocol != 
        
          null
        
        
          ) {

                setProtocolHandlerClassName(protocol);

            } 
        
        
          else
        
        
           {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.http11.Http11AprProtocol"
        
          );

            }

        } 
        
        
          else
        
        
           {

            
        
        
          if
        
         ("HTTP/1.1"
        
          .equals(protocol)) {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.http11.Http11Protocol"
        
          );

            } 
        
        
          else
        
        
          if
        
         ("AJP/1.3"
        
          .equals(protocol)) {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.ajp.AjpProtocol"
        
          );

            } 
        
        
          else
        
        
          if
        
         (protocol != 
        
          null
        
        
          ) {

                setProtocolHandlerClassName(protocol);

            }

        }
        
      
View Code

  然后根据setProtocol方法设置的protocol handler进行实例化,在setProtocol方法中调用的setProtocolHandlerClassName方法,如下:

      
          public
      
      
        void
      
      
         setProtocolHandlerClassName(String protocolHandlerClassName) {



        
      
      
        this
      
      .protocolHandlerClassName =
      
         protocolHandlerClassName;



    }
      
    

  给connector的变量protocolHandlerClassName赋值,然后根据protocolHandlerClassName的值进行实例化。进而赋值给protocolHandler 变量。

  然后是方法createObjectNameKeyProperties,该方法的作用是将请求的address参数拼接成字符串,包括type,port。下面是代码实现:  

        
          protected
        
        
           String createObjectNameKeyProperties(String type) {



        Object addressObj 
        
        = getProperty("address"
        
          );



        StringBuilder sb 
        
        = 
        
          new
        
         StringBuilder("type="
        
          );

        sb.append(type);

        sb.append(
        
        ",port="
        
          );

        
        
        
          int
        
         port =
        
           getPort();

        
        
        
          if
        
         (port > 0
        
          ) {

            sb.append(getPort());

        } 
        
        
          else
        
        
           {

            sb.append(
        
        "auto-"
        
          );

            sb.append(getProperty(
        
        "nameIndex"
        
          ));

        }

        String address 
        
        = ""
        
          ;

        
        
        
          if
        
         (addressObj 
        
          instanceof
        
        
           InetAddress) {

            address 
        
        =
        
           ((InetAddress) addressObj).getHostAddress();

        } 
        
        
          else
        
        
          if
        
         (addressObj != 
        
          null
        
        
          ) {

            address 
        
        =
        
           addressObj.toString();

        }

        
        
        
          if
        
         (address.length() > 0
        
          ) {

            sb.append(
        
        ",address="
        
          );

            sb.append(ObjectName.quote(address));

        }

        
        
        
          return
        
        
           sb.toString();

    }
        
      
View Code

  创建一个Request对象,Request是一个对Coyote Request的封装,Coyote 这个东西很奇怪,是狼的意思,也不知道为什么外国人喜欢用动物名来给一个技术命名,hadoop,hive,pig等,说Coyote其实是对Socket的一个封装,将Socket的请求和相应封装成一个个Request和Response,具体如何封装,都包涵什么信息等内容以后展开说明:

        
          public
        
        
           Request createRequest() {

        Request request 
        
        = 
        
          new
        
        
           Request();

        request.setConnector(
        
        
          this
        
        
          );

        
        
        
          return
        
        
           (request);

    }
        
      
View Code

  创建一个Response对象:

        
          public
        
        
           Response createResponse() {

        Response response 
        
        = 
        
          new
        
        
           Response();

        response.setConnector(
        
        
          this
        
        
          );

        
        
        
          return
        
        
           (response);

    }
        
      
View Code

  这里面值得注意的地方就是在request和response中,都有setConnector方法,所有connector是request和response的一个属性。

  下面看方法destroyInternal,这个方法是在LifecycleMBeanBase类中定义的,用来销毁mapperListener,protocolHandler从Service中移除这个Connector对象,代码实现如下:  

        
           @Override

    
        
        
          protected
        
        
          void
        
         destroyInternal() 
        
          throws
        
        
           LifecycleException {

        mapperListener.destroy();



        
        
        
          try
        
        
           {

            protocolHandler.destroy();

        } 
        
        
          catch
        
        
           (Exception e) {

            
        
        
          throw
        
        
          new
        
        
           LifecycleException

                (sm.getString

                 (
        
        "coyoteConnector.protocolHandlerDestroyFailed"
        
          ), e);

        }



        
        
        
          if
        
         (getService() != 
        
          null
        
        
          ) {

            getService().removeConnector(
        
        
          this
        
        
          );

        }



        
        
        
          super
        
        
          .destroyInternal();

    }
        
      
View Code

  设置和获取是否允许Trace方法的执行:  

        
          public
        
        
          void
        
         setAllowTrace(
        
          boolean
        
        
           allowTrace) {



        
        
        
          this
        
        .allowTrace =
        
           allowTrace;

        setProperty(
        
        "allowTrace"
        
          , String.valueOf(allowTrace));



    }




        
        
          public
        
        
          boolean
        
        
           getAllowTrace() {



        
        
        
          return
        
         (
        
          this
        
        
          .allowTrace);



    }
        
      
View Code

  设置和获取异步请求的过期时间:  

        
          public
        
        
          void
        
         setAsyncTimeout(
        
          long
        
        
           asyncTimeout) {



        
        
        
          this
        
        .asyncTimeout=
        
           asyncTimeout;

        setProperty(
        
        "asyncTimeout"
        
          , String.valueOf(asyncTimeout));



    }


        
        
          public
        
        
          long
        
        
           getAsyncTimeout() {



        
        
        
          return
        
        
           asyncTimeout;



    }
        
      
View Code

  配置和获取参数,参数这部分在前面的章节已经提到过了:

        
          public
        
        
          void
        
        
           setAttribute(String name, Object value) {

        setProperty(name, String.valueOf(value));

    }

 
        
        
          public
        
        
           Object getAttribute(String name) {

        
        
        
          return
        
        
           getProperty(name);

    }
        
      
View Code

  剩下的方法都是设置和获取前面定义的变量的值。

  Server的主要接口已经介绍完了,下面看一下一些关键类的实现:

  Server接口的标准实现是StandardServer类,同时StandServer也继承了LifecycleMBeanBase类,看一下StandardServer中几个重要方法的实现:

查看tomcat启动文件都干点啥---server对象

  找几个重要的方法说明一下:

  向保存Connector的数组中添加新的Connector对象的方法addConnector,代码实现如下:  

        
          public
        
        
          void
        
        
           addConnector(Connector connector) {



        
        
        
          synchronized
        
        
           (connectors) {

            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
        
        
           (getState().isAvailable()) {

                
        
        
          try
        
        
           {

                    connector.start();

                } 
        
        
          catch
        
        
           (LifecycleException e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.startFailed"
        
          ,

                            connector), e);

                }

            }



            
        
        
          //
        
        
           Report this property change to interested listeners
        
        

            support.firePropertyChange("connector", 
        
          null
        
        
          , connector);

        }



    }
        
      
View Code

  首先要把Connector和Serice做关联,connector.setService(this),然后将要添加的connector对象添加到保存Connector对象的数组中,此处使用数组,完全是处于效率的考虑。然后查看当前Server对象的状态,如果状态合法的话,那么启动添加的connector对象。然后在更改此Connector的状态。

  返回Connector集合:  

        
          @Override

    
        
        
          public
        
        
           Connector[] findConnectors() {



        
        
        
          return
        
        
           (connectors);



    }
        
      
View Code

  在Connector集合中移除connector:  

        
          public
        
        
          void
        
        
           removeConnector(Connector connector) {



        
        
        
          synchronized
        
        
           (connectors) {

            
        
        
          int
        
         j = -1
        
          ;

            
        
        
          for
        
         (
        
          int
        
         i = 0; i < connectors.length; i++
        
          ) {

                
        
        
          if
        
         (connector ==
        
           connectors[i]) {

                    j 
        
        =
        
           i;

                    
        
        
          break
        
        
          ;

                }

            }

            
        
        
          if
        
         (j < 0
        
          )

                
        
        
          return
        
        
          ;

            
        
        
          if
        
        
           (connectors[j].getState().isAvailable()) {

                
        
        
          try
        
        
           {

                    connectors[j].stop();

                } 
        
        
          catch
        
        
           (LifecycleException e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.stopFailed"
        
          ,

                            connectors[j]), e);

                }

            }

            connector.setService(
        
        
          null
        
        
          );

            
        
        
          int
        
         k = 0
        
          ;

            Connector results[] 
        
        = 
        
          new
        
         Connector[connectors.length - 1
        
          ];

            
        
        
          for
        
         (
        
          int
        
         i = 0; i < connectors.length; i++
        
          ) {

                
        
        
          if
        
         (i !=
        
           j)

                    results[k
        
        ++] =
        
           connectors[i];

            }

            connectors 
        
        =
        
           results;



            
        
        
          //
        
        
           Report this property change to interested listeners
        
        

            support.firePropertyChange("connector", connector, 
        
          null
        
        
          );

        }



    }
        
      
View Code

  首先遍历Connector集合,找到要移除的connector,如果指定的connector对象状态合法,那么调用该connector的stop方法,然后将指定的connector对象关联的Server置为null,剩下的内容就是整理移除connector对象的Connector集合。

  设置Container方法,该container对象处理Service中所有connector中的请求:  

        
          public
        
        
          void
        
        
           setContainer(Container container) {



        Container oldContainer 
        
        = 
        
          this
        
        
          .container;

        
        
        
          if
        
         ((oldContainer != 
        
          null
        
        ) && (oldContainer 
        
          instanceof
        
        
           Engine))

            ((Engine) oldContainer).setService(
        
        
          null
        
        
          );

        
        
        
          this
        
        .container =
        
           container;

        
        
        
          if
        
         ((
        
          this
        
        .container != 
        
          null
        
        ) && (
        
          this
        
        .container 
        
          instanceof
        
        
           Engine))

            ((Engine) 
        
        
          this
        
        .container).setService(
        
          this
        
        
          );

        
        
        
          if
        
         (getState().isAvailable() && (
        
          this
        
        .container != 
        
          null
        
        
          )) {

            
        
        
          try
        
        
           {

                
        
        
          this
        
        
          .container.start();

            } 
        
        
          catch
        
        
           (LifecycleException e) {

                
        
        
          //
        
        
           Ignore
        
        
                      }

        }

        
        
        
          if
        
         (getState().isAvailable() && (oldContainer != 
        
          null
        
        
          )) {

            
        
        
          try
        
        
           {

                oldContainer.stop();

            } 
        
        
          catch
        
        
           (LifecycleException e) {

                
        
        
          //
        
        
           Ignore
        
        
                      }

        }



        
        
        
          //
        
        
           Report this property change to interested listeners
        
        

        support.firePropertyChange("container", oldContainer, 
        
          this
        
        
          .container);



    }
        
      
View Code

  首先是处理这个Server中原有的Container,原来可能有Container也有可能没有,所以要做判断,如果存在的话,解除和Service的关联,然后要处理新的container对象。关联Service,启动Container。

  由于Service中只有一个Container,所以没有移除Container方法,在设置的时候其实是完成了删除更新的操作。

  看一下startInternal方法:  

        
          protected
        
        
          void
        
         startInternal() 
        
          throws
        
        
           LifecycleException {



        
        
        
          if
        
        
          (log.isInfoEnabled())

            log.info(sm.getString(
        
        "standardService.start.name", 
        
          this
        
        
          .name));

        setState(LifecycleState.STARTING);



        
        
        
          //
        
        
           Start our defined Container first
        
        
          if
        
         (container != 
        
          null
        
        
          ) {

            
        
        
          synchronized
        
        
           (container) {

                container.start();

            }

        }



        
        
        
          synchronized
        
        
           (executors) {

            
        
        
          for
        
        
           (Executor executor: executors) {

                executor.start();

            }

        }



        
        
        
          //
        
        
           Start our defined Connectors second
        
        
          synchronized
        
        
           (connectors) {

            
        
        
          for
        
        
           (Connector connector: connectors) {

                
        
        
          try
        
        
           {

                    
        
        
          //
        
        
           If it has already failed, don't try and start it
        
        
          if
        
         (connector.getState() !=
        
           LifecycleState.FAILED) {

                        connector.start();

                    }

                } 
        
        
          catch
        
        
           (Exception e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.startFailed"
        
          ,

                            connector), e);

                }

            }

        }

    }
        
      
View Code

  该方法就是逐一启动Service中的组件,Container,Executor,Connector。

  stopInternal方法:  

        
          protected
        
        
          void
        
         stopInternal() 
        
          throws
        
        
           LifecycleException {



        
        
        
          //
        
        
           Pause connectors first
        
        
          synchronized
        
        
           (connectors) {

            
        
        
          for
        
        
           (Connector connector: connectors) {

                
        
        
          try
        
        
           {

                    connector.pause();

                } 
        
        
          catch
        
        
           (Exception e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.pauseFailed"
        
          ,

                            connector), e);

                }

            }

        }



        
        
        
          if
        
        
          (log.isInfoEnabled())

            log.info(sm.getString(
        
        "standardService.stop.name", 
        
          this
        
        
          .name));

        setState(LifecycleState.STOPPING);



        
        
        
          //
        
        
           Stop our defined Container second
        
        
          if
        
         (container != 
        
          null
        
        
          ) {

            
        
        
          synchronized
        
        
           (container) {

                container.stop();

            }

        }



        
        
        
          //
        
        
           Now stop the connectors
        
        
          synchronized
        
        
           (connectors) {

            
        
        
          for
        
        
           (Connector connector: connectors) {

                
        
        
          if
        
         (!
        
          LifecycleState.STARTED.equals(

                        connector.getState())) {

                    
        
        
          //
        
        
           Connectors only need stopping if they are currently

                    
        
        
          //
        
        
           started. They may have failed to start or may have been

                    
        
        
          //
        
        
           stopped (e.g. via a JMX call)
        
        
          continue
        
        
          ;

                }

                
        
        
          try
        
        
           {

                    connector.stop();

                } 
        
        
          catch
        
        
           (Exception e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.stopFailed"
        
          ,

                            connector), e);

                }

            }

        }



        
        
        
          synchronized
        
        
           (executors) {

            
        
        
          for
        
        
           (Executor executor: executors) {

                executor.stop();

            }

        }

    }
        
      
View Code

  由这两个方法也能看出来Lifecycle对于个个组件生命周期的一致的生命周期的管理机制。

  其实最开始想用本章说一下如何构建Server,但是觉得还是有必要将Server中的内容展开说明一下,在说如果构建的话可能更好理解。所以就有了这个只是具有说明意义的一节。 

查看tomcat启动文件都干点啥---server对象


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论