• Tomcat中容器是什么以及容器与容器之间的数量关系。


    Tomcat容器到底是什么

    学java有一小段时间了,一直使用Tomcat,也知道Tomcat是一个大的Servlet容器,里面还有许多子容器,容器之间都是相互嵌套的。也看过一下接收Tomcat的文章,都是一幅图,图中有好多个框框相互嵌套,表示容器与容器之间的相互嵌套,也没什么说明,把我看得云里雾里的。所以要想了解的更多必须自己探索一下。

      现在把自己学到的一点点知识记下来,以免忘记了。

      都说Tomcat是一个容器,那么这个容器到底是什么东西,因为说它是一个容器我还是觉得有点抽象,而我看了很多文章都没看到有人说。所以,我想知道Tomcat的本质。脑袋有点转不过弯来,写到这里才发现既然Tomcat是用java写的那它的容器的本质应该就是java类啦。

      在开始探索之前我就知道Tomcat中有Server、Service、Engine、Host.....等容器。这些容器与容器之间相互嵌套。既然这些容器的本质就是实实在在的java类(容器就是java类,已经够具体了,这样我才能理解,因为我天天写java类 ^v^ ),那这些不同的容器分别使用什么样的java类来描述的呢???我点是我想要知道的。

      经过一番探索,知道这些容器都是有生命周期的java类,他们都继承了共同的接口 Lifecycle 。所以Lifecycle就是这些容器这些java类的顶层接口了。下面是我画的继承体系图。

    图一:图片保存下来看吧,博客园的图片编辑无语,改天好好研究一下怎么让他弹出来再改。

     通过图中的类名就可以知道哪些类是表示Server,哪些是表示Service哪些是。。。。。。

    Tomcat中的这些容器都是有生命周期的容器,那么它的类肯定就有声明周期方法了。先看看顶层接口 Lifecycle ,这个接口里面主要定义了一些生命周期的方法。所以,继承自这个接口的所有容器都有生命周期。

    图二:

     init()方法:初始化容器组件,它必须在启动容器之前调用。它会创建许多对象。

    start():启动容器,比如启动一个Server。

    stop():停止执行

    destroy():销毁这个容器。

    Server容器:一个StandardServer类实例就表示一个Server容器

    Service容器:一个StandardService类实例就表示一个Service容器

    Engine容器:一个StandardEngine类实例就表示一个Engine容器。

    Host容器:一个StandardHost类实例就表示一个Host容器。

    Context容器:一个StandardContext类实例就表示一个Context容器。

    Wrapper容器:一个StandardWrapper类实例就表示一个Wrapper容器。

    以上一共有六种类型的容器,从上到下嵌套,也就是Server容器里面有Service容器,Service容器里面有Engine容器。。。。。。这就是这些容器之间的嵌套关系。

    需要注意的是,这些容器之间存在父子关系,但是他们对应的java类之间却不是父子关系。由图一可以看出来。

    父容器与子容器之间的数量关系

    这些父容器和子容器之间有什么样的数量关系呢???

    一个Server容器可以有多个Service容器

       /**
         * The set of Services associated with this Server.用一个数组来保存子容器的引用
         */
        private Service services[] = new Service[0];

    一个Service容器只可以有一个子容器。

    /**
         * The Container associated with this Service. (In the case of the
         * org.apache.catalina.startup.Embedded subclass, this holds the most
         * recently added Engine.)
        它不是用一个数组来保存子容器的引用的。所以直接的子容器只有一个。
    */ protected Container container = null;

    这里用Container来表示子容器,根据图一可以看出,Container是Engine、Host、Context、Wrapper 接口的父接口,所以Service容器下面的子容器可能是Engine、Host、Context、Wrapper。但是我觉得一般情况下Service的子容器都是Engine容器吧。
    一个Engine容器里面可以有多个 Host 容器

        /**
         * Add a child Container, only if the proposed child is an implementation
         * of Host.
         *
         * @param child Child container to be added
         */
        @Override
        public void addChild(Container child) {
    
            if (!(child instanceof Host))//这里说明Engine的子容器只能是Host
                throw new IllegalArgumentException
                    (sm.getString("standardEngine.notHost"));
            super.addChild(child);
    
        }

    一个Host容器里可以有多个 Context 容器。

        /**
         * Add a child Container, only if the proposed child is an implementation
         * of Context.
         *
         * @param child Child container to be added
         */
        @Override
        public void addChild(Container child) {
    
            child.addLifecycleListener(new MemoryLeakTrackingListener());
    
            if (!(child instanceof Context))//这里说明Host容器的子容器只能是Context容器
                throw new IllegalArgumentException
                    (sm.getString("standardHost.notContext"));
            super.addChild(child);
    
        }

    一个Host容器中可以有多个Wrapper容器。

        /**
         * Add a child Container, only if the proposed child is an implementation
         * of Wrapper.
         *
         * @param child Child container to be added
         *
         * @exception IllegalArgumentException if the proposed container is
         *  not an implementation of Wrapper
         */
        @Override
        public void addChild(Container child) {
    
            // Global JspServlet
            Wrapper oldJspServlet = null;
    
            if (!(child instanceof Wrapper)) {//这里说明Context容器的子容器只能是Wrapper容器。
                throw new IllegalArgumentException
                    (sm.getString("standardContext.notWrapper"));
            }
          //这里删除了部分代码
        
        }

    Wrapper容器下面不允许再有子容器。Wrapper容器是最底层的容器。如果添加子容器的话会抛出异常。

        /**
         * Refuse to add a child Container, because Wrappers are the lowest level
         * of the Container hierarchy.
         *
         * @param child Child container to be added
         */
        @Override
        public void addChild(Container child) {
    
            throw new IllegalStateException
                (sm.getString("standardWrapper.notChild"));
    
        }

    服务器接收到请求信息后如何传到我们编写的HttpServlet的呢??如果是SpringMVC的话会先到DispatcherServlet再到Controller,而DispatcherServlet也是HttpServlet的一个间接子类。在下一篇文章Tomcat是如何将请求一步步传递到我们编写的HttpServlet类中的

  • 相关阅读:
    二叉树中和为某一值的路径
    二叉搜索树的后序遍历序列(important!)
    从上往下打印二叉树
    最小的k个数(important!)
    扑克牌顺子
    栈的压入、弹出序列(important!)
    和为s的连续正数序列(important!)
    数组中只出现一次的数字
    fgets()函数以及fputs()函数
    C语言中的指针
  • 原文地址:https://www.cnblogs.com/GooPolaris/p/8111837.html
Copyright © 2020-2023  润新知