之前的项目还是有些问题的,例如

1 只能有一个连接器,只能处理http请求,无法添加另外一个连接器用来处理https。

2 对容器的关闭只能是粗暴的关闭Bootstrap。

服务器组件

org.apache.catalina.Server接口的实例用来表示Catalina的整个servlet引擎。

我们使用Server就是因为,它用一种优雅的方式来启动/关闭整个系统。

下面是启动和停止机制是如何工作的。当服务器启动的时候,它启动它内部的所有组件。然后无限期的等待关闭命令,如果你想要关闭系统,发送一个关闭命令道指定端口即可。当服务器收到正确的关闭指令后,它停止所有组件的服务。

服务器还使用了另外一个组件,即服务组件,它用来持有组件,例如容器或者一个多个的连接器。服务组件将在本章的 service 小节中介绍。(注意有服务器组件,也有服务组件,这两个是不一样的。)

Server接口中属性 shutdown 用来持有一个停止服务的指令。属性 port 则是服务器等待关闭命令的端口。可以调用服务器的 addService 方法将服务添加到服务器。使用removeService 方法将服务删除。findServices 返回所有服务器中所有的服务。

StandardServer类

StandardServer类是Server接口的标准实现。在这里,我们主要介绍它的四个方法。initialize(),start(),stop(),await();

我们一个一个来说。

initialize方法

    public void initialize() throws LifecycleException {
        if (initialized)
            throw new LifecycleException (
                sm.getString("standardServer.initialize.initialized"));
        initialized = true;

        // Initialize our defined Services
        for (int i = 0; i < services.length; i++) {
            services[i].initialize();
        }
    }

我们能看到这里使用了一个initialized来标识服务器是否已经初始化,同时初始化它所包含的服务组件。

另外在stop中,initialized并没有更改,因此如果服务器先初始化,再关闭,等再次初始化的时候会抛出异常。

start方法

public void start() throws LifecycleException {

        // Validate and update our current component state
        if (started)
            throw new LifecycleException
                (sm.getString("standardServer.start.started"));
        // Notify our interested LifecycleListeners
    ...
        started = true;

        // Start our defined Services
        synchronized (services) {
            for (int i = 0; i < services.length; i++) {
                if (services[i] instanceof Lifecycle)
                    ((Lifecycle) services[i]).start();
            }
        }

        // Notify our interested LifecycleListeners
       ...
    }

和初始化干的事情差不多,循环启动它所关联的服务组件。另外在stop方法中,started会被置为false。

stop方法

public void stop() throws LifecycleException {
        // Validate and update our current component state
        if (!started)
            throw new LifecycleException
                (sm.getString("standardServer.stop.notStarted"));

        // Notify our interested LifecycleListeners
    ...
        started = false;

        // Stop our defined Services
        for (int i = 0; i < services.length; i++) {
            if (services[i] instanceof Lifecycle)
                ((Lifecycle) services[i]).stop();
        }

        // Notify our interested LifecycleListeners
       ...
    }

关闭所有的服务组件。

await方法

这里不再贴出代码,await做的事就是监听8005端口,如果用户给8005端口发来"SHUTDOWN"就关闭serverSocket,然后await方法就执行完了。



现在再说说initialize方法,start方法,await方法,stop四者者都是在Bootstrap里调用的。

当await方法执行完毕后,就会调用服务器的stop方法。

Service接口

org.apache.catalina.Service 接口用于表示服务。一个服务可以有一个容器和多个连接器。你可以添加多个连接器 ,并将它们跟容器相关联。

StandardService类

StandardService是Service接口的标准实现。

容器与连接器

一个 StandardService 实例包括两种组件:一个容器和多个连接器。多个连接器可以使得 Tomcat 能服务于多个协议。一个协议用处处理 HTTP 请求,另一个用于处理 HTTPS 请求。

StandardService 类用 container 变量来持有容器实例,用 connectors 数组来持有所有的连接器

private Container container = null;
private Connector connectors[] = new Connector[0];

要将一个容器跟一个服务相关联,可以使用它的 setContainer 方法,

在setContainer中,会把container传递给每一个connector。

        synchronized (connectors) {
            for (int i = 0; i < connectors.length; i++)
                connectors[i].setContainer(this.container);
        }

要给一个服务添加连接器,可以使用 addConnector 方法。在添加连接器的同时也会初始化他们。

要删除一个连接器,可以使用 removeConnector 方法。

与生命周期相关的方法

这里主要包含三个方法,initialize,start,stop。

initialize功能就是调用所以连接器的initialize方法。

start功能就是启动容器和若干个连接器。

stop功能就是关闭容器和若干个连接器。

服务组件的这三个方法都会在服务器组件里相应的方法里被调用,而服务器组件的这三个方法是在Bootstrap里调用的。

应用程序

这里主要是两个类,一个是 Bootstrap 启动程序,另一个是 Stopper 类用来停止它。

Bootstrap类

public static void main(String args[]){
......

    Service service = new StandardService();
    service.setName("Stand-alone Service");

    Server server = new StandardServer();
    server.addService(service);      //把服务组件添加到服务器组件里
    service.addConnector(connector); //把连接器关联到服务组件里

    //StandardService class's setContainer will call all its connector's setContainer method
    service.setContainer(engine);    //容器并没有直接和连接器关联,而是和服务组件关联

    // Start the new server
    if (server instanceof Lifecycle) {
      try {
        server.initialize();         //调用initialize,start,await方法
        ((Lifecycle) server).start();//这里会调用服务组件的start,来调用连接器与容器的start
                                 //连接器会在8080上等待消息....
        server.await();              //除非在8005端口收到了SHUTDOWN信息 这里会一直循环
        // the program waits until the await method returns,
        // i.e. until a shutdown command is received.
      }
      catch (LifecycleException e) {
        e.printStackTrace(System.out);
      }
    }

    // Shut down the server
    if (server instanceof Lifecycle) {
      try {
        ((Lifecycle) server).stop();  //收到了SHUTDOWM信息,关闭服务器组件
      }
      catch (LifecycleException e) {
        e.printStackTrace(System.out);
      }
    }
  }

Stopper类

public class Stopper {

  public static void main(String[] args) {
    // the following code is taken from the Stop method of
    // the org.apache.catalina.startup.Catalina class
    int port = 8005;
    try {
      Socket socket = new Socket("127.0.0.1", port);
      OutputStream stream = socket.getOutputStream();
      String shutdown = "SHUTDOWN";
      for (int i = 0; i < shutdown.length(); i++)
        stream.write(shutdown.charAt(i));
      stream.flush();
      stream.close();
      socket.close();
      System.out.println("The server was successfully shut down.");
    }
    catch (IOException e) {
      System.out.println("Error. The server has not been started.");
    }
  }
}

How tomcat works 读书笔记十四 服务器组件和服务组件的更多相关文章

  1. How tomcat works 读书笔记十五 Digester库 上

    Digester库 在前面的几个章节里,我们对tomcat里各个组件的配置完全是使用写硬编码的形式完成的. 如 Context context = new StandardContext(); Loa ...

  2. How tomcat works 读书笔记十五 Digester库 下

    在这一节里我们说说ContextConfig这个类. 这个类在很早的时候我们就已经使用了(之前那个叫SimpleContextConfig),但是在之前它干的事情都很简单,就是吧context里的co ...

  3. How tomcat works 读书笔记十二 StandardContext 下

    对重载的支持 tomcat里容器对重载功能的支持是依靠Load的(在目前就是WebLoader).当在绑定载入器的容器时 public void setContainer(Container cont ...

  4. How tomcat works 读书笔记十二 StandardContext 上

    在tomcat4中,StandardContext.java是最大的一个类,有117k.废话不说,开始分析吧. 其实要分析StandardContext,也就主要分析两个方法,一个start,一个in ...

  5. how tomcat works 读书笔记(二)----------一个简单的servlet容器

    app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...

  6. how tomcat works 读书笔记四 tomcat的默认连接器

    事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...

  7. how tomcat works 读书笔记(一)----------一个简单的web服务器

    http协议 若是两个人能正常的说话交流,那么他们间必定有一套统一的语言规则<在网络上服务器与客户端能交流也依赖与一套规则,它就是我们说的http规则(超文本传输协议Hypertext tran ...

  8. how tomcat works 读书笔记(一)----------一个简单的webserver

    http协议 若是两个人能正常的说话交流,那么他们间必然有一套统一的语言规则<在网络上server与client能交流也依赖与一套规则,它就是我们说的http规则(超文本传输协议Hypertex ...

  9. How Tomcat Works读书笔记三-------连接器

    几个概念 HttpServlet,Servlet Servlet是一个接口,定义了一种网络服务,我们所有的servlet都要实现它(或它的子类) HttpServlet是一个抽象类,它针对的就是htt ...

随机推荐

  1. Java命名和目录接口——JNDI

    JNDI即Java命名和目录接口(JavaNaming and Directory Interface),它属于J2EE规范范畴,是J2EE的核心技术之一,提供了一组接口.类和关于命名空间的概念.JD ...

  2. linux及windows文件共享

    http://blog.csdn.net/pipisorry/article/details/51812022 本文主要说明 linux和windows文件共享, windows和ubuntu互相访问 ...

  3. Python模块探秘 Smtplib发送带有各种附件的邮件

    这两天对Python的邮件模块比较感兴趣,于是就查了查资料.同时在实际的编码过程中也遇到了各种各样的问题.下面我就来分享一下我与smtplib的故事. 前提条件 我的上一篇博文里面讲解了,发送邮件必须 ...

  4. 2.6、Android Studio创建可伸缩的图片(9-patch文件)

    Draw 9-patch工具是一个所见即所得编辑器,允许你创建可以自动改变大小来适应视图的内容和屏幕的大小. 以下是使用Draw 9-path工具快速创建一个NinePatch图片. 1. 在命令行中 ...

  5. love~LBJ,奥布莱恩神杯3

    时间:2016年6月20日8:00:地点:美国金州甲骨文(Oracle)球馆:事件:G7大战,又一次见证伟大赛季奥布莱恩神杯得主--金州勇士VS克利夫兰骑士......     可以说,这是NBA以来 ...

  6. Java-IO之字符输入输出流(Reader和Writer)

    以字符为单位的输入流的公共父类是Reader: 以字符为单位的输出流的超类是Writer: 基于JDK8的Reader的源码: public abstract class Reader impleme ...

  7. 手把手教你轻松实现listview上拉加载

    上篇讲了如何简单快速的的实现listview下拉刷新,那么本篇将讲解如何简单快速的实现上拉加载更多.其实,如果你已经理解了下拉刷新的实现过程,那么实现上拉加载更多将变得轻松起来,原理完全一致,甚至实现 ...

  8. 精通CSS+DIV网页样式与布局--页面背景

    上篇博客,我们主要简单的总结了CSS的图片效果,我们这回来讲讲CSS如何对网页的背景进行设置,网页的背景是整个网页的重要组成部分,她直接决定了整个网页的风格和色调.这篇博客简单的总结一下如何用CSS来 ...

  9. [sersync] github镜像 二进制包

    这几天在搞数据的本地备份和远程备份的事情,用到了sersync这个国产的同步工具,可是发现他托管在google code,需要fanqiang才能下载, 于是就弄了一个github的镜像,顺便把64位 ...

  10. AngularJS进阶(四十)创建模块、服务

    AngularJS进阶(四十)创建模块.服务 学习要点 使用模块构架应用 创建和使用服务 为什么要使用和创建服务与模块? 服务允许你打包可重用的功能,使之能在此应用中使用. 模块允许你打包可重用的功能 ...