Tomcat源码阅读笔记

概况:

Tomcat 的整体结构图java

Tomcat 的整体结构图
做为大天朝子民的咱们不难发现图中Tomcat的两个核心组件: ConnectorContainer

Connector Container
负责和外界取得联系,即创建链接(一个Connetor组件只能处理一种请求协议,例如一个Connector组件不能既处理http方式的请求又能处理https请求,所以须要多个Connector组件。) 负责处理Connector接受的请求,主要是处理内部事务(Container包含了Engine,Host,Context,Wrapper四个组件,负责处理请求相关的逻辑)

Service 只是在 Connector 和 Container 外面多包一层,把它们组装在一块儿,对外提供服务,一个 Service 能够设置多个 Connector,可是只能有一个 Container 容器。 Server控制Tomcat的整个生命周期。数组


认识 StandardService:

Service接口 Lifecycle接口
关联Connector和Container,同时初始化它下面的其余组件 控制全部组件的生命周期

StandardService实现了Service接口和Lifecycle接口,这样它就能够控制它下面组件的生命周期了;除了对Service和Lifecycle接口方法的实现它还有几个方法是用于事件监听方法的实现。app

图 Service 接口 性能

图 Service 接口
图 StandardService 类
图 StandardService 类

源码剖析
下面看一下 StandardService 中主要的几个方法实现的代码,下面是 setContaineraddConnector 方法的源码:
清单 1. StandardService. SetContainerthis

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 (started && (this.container != null) && (this.container instanceof Lifecycle)) {
        try {
            ((Lifecycle) this.container).start();
        } catch (LifecycleException e) {
            ;
        }
    }
    synchronized (connectors) {
        for (int i = 0; i < connectors.length; i++)
            connectors[i].setContainer(this.container);
    }
    if (started && (oldContainer != null) && (oldContainer instanceof Lifecycle)) {
        try {
            ((Lifecycle) oldContainer).stop();
        } catch (LifecycleException e) {
            ;
        }
    }
    support.firePropertyChange("container", oldContainer, this.container);
}
复制代码

这段代码很简单,其实就是先判断当前的这个 Service 有没有已经关联了 Container,若是已经关联了,那么去掉这个关联关系—— oldContainer.setService(null)。若是这个 oldContainer 已经被启动了,结束它的生命周期。而后再替换新的关联、再初始化并开始这个新的 Container 的生命周期。最后将这个过程通知感兴趣的事件监听程序。
清单 2. StandardService. addConnectorspa

public void addConnector(Connector connector) {
    synchronized (connectors) {
        connector.setContainer(this.container);
        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) {
                ;
            }
        }
        support.firePropertyChange("connector", null, connector);
    }
}
复制代码

上面是 addConnector 方法,这个方法也很简单,首先是设置关联关系,而后是初始化工做,开始新的生命周期。code

注意: Connector 用的是数组而不是 List 集合,这个从性能角度考虑能够理解,有趣的是这里用了数组可是并无向咱们日常那样,一开始就分配一个固定大小的数组,它这里的实现机制是:从新建立一个当前大小的数组对象,而后将原来的数组对象 copy 到新的数组中,这种方式实现了相似的动态数组的功能,这种实现方式,值得咱们之后拿来借鉴。cdn


认识StandardServer

Server 的任务:就是要可以提供一个接口让其它程序可以访问到这个 Service 集合、同时要维护它所包含的全部 Service 的生命周期,包括如何初始化、如何结束服务、如何找到别人要访问的 Service。对象

Server 类结构图 blog

Server 类结构图

它的标准实现类 StandardServer 实现了上面这些方法,同时也实现了 Lifecycle、MbeanRegistration 两个接口的全部方法,下面主要看一下 StandardServer 重要的一个方法 addService 的实现:

public void addService(Service service) {
    service.setServer(this);
    synchronized (services) {
        Service results[] = new Service[services.length + 1];
        System.arraycopy(services, 0, results, 0, services.length);
        results[services.length] = service;
        services = results;
        if (initialized) {
            try {
                service.initialize();
            } catch (LifecycleException e) {
                e.printStackTrace(System.err);
            }
        }
        if (started && (service instanceof Lifecycle)) {
            try {
                ((Lifecycle) service).start();
            } catch (LifecycleException e) {
                ;
            }
        }
        support.firePropertyChange("service", null, service);
    }
}
复制代码

从上面第一句就知道了 Service 和 Server 是相互关联的,Server 也是和 Service 管理 Connector 同样管理它,也是将 Service 放在一个数组中,后面部分的代码也是管理这个新加进来的 Service 的生命周期。Tomcat6 中也是没有什么变化的。

相关文章
相关标签/搜索