(三)Server和Service

  通过Server可以让我们以一种优雅的方式来启动/关闭整个系统。
  从Catalina类看出,启动整个服务只需要通过server.start()就可以,它会带动其中所有组件的启动,然后无期限的等待关闭命令, 关闭系统,则是通过向指定端口发送一条命令, 调用server.stop()就可关闭所有的组件.

StandardServer类

  Tomcat使用的就是这个标准Server类,它实现了Server接口类

public final class StandardServer
    implements Lifecycle, Server {
    
    public StandardServer() {
        super();
        ServerFactory.setServer(this);

        globalNamingResources = new NamingResources();      //????????这些有什么用
        globalNamingResources.setContainer(this);

        if (isUseNaming()) {
            if (namingContextListener == null) {     //????????这些有什么用
                namingContextListener = new NamingContextListener();
                namingContextListener.setDebug(getDebug());
                addLifecycleListener(namingContextListener);
            }
        }
    }
    
}

  StandardServer的构造函数中好像是初始化Global naming resources.(究竟有什么用,和启动参数-nonaming有什么关系,naming有什么用),后续研究
  现阶段关心的是Server类中的初始化、等待、开始、停止方法。

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的变量来防止服务器组件初始化两次。依次调用server包含的service的初始化过程。值得注意的是,stop()函数并没有重置initialized为false,所以如果服务器组件关闭后再启动,是不会进行初始化的

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
    lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); //结尾处有细讲Listener

    lifecycle.fireLifecycleEvent(START_EVENT, null);
    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
    lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

}

  防止重复启动。依次调用server包含的service的start()函数。stop()函数会重置started为false

wait()
public void await() {
        // Set up a server socket to wait on
        ServerSocket serverSocket = null;
        try {
            serverSocket =
                new ServerSocket(port, 1,
                                 InetAddress.getByName("127.0.0.1"));
        } catch (IOException e) {
            System.err.println("StandardServer.await: create[" + port
                               + "]: " + e);
            e.printStackTrace();
            System.exit(1);
        }

        // Loop waiting for a connection and a valid command
        while (true) {
            // Wait for the next connection
            Socket socket = null;
            InputStream stream = null;
            try {
                socket = serverSocket.accept();
                socket.setSoTimeout(10 * 1000);  // Ten seconds
                stream = socket.getInputStream();
            } catch (AccessControlException ace) {
                System.err.println("StandardServer.accept security exception: "
                                   + ace.getMessage());
                continue;
            } catch (IOException e) {
                System.err.println("StandardServer.await: accept: " + e);
                e.printStackTrace();
                System.exit(1);
            }

            // Read a set of characters from the socket
            StringBuffer command = new StringBuffer();
            int expected = 1024; // Cut off to avoid DoS attack
            while (expected < shutdown.length()) {
                if (random == null)
                    random = new Random(System.currentTimeMillis());
                expected += (random.nextInt() % 1024);
            }
            while (expected > 0) {
                int ch = -1;
                try {
                    ch = stream.read();
                } catch (IOException e) {
                    System.err.println("StandardServer.await: read: " + e);
                    e.printStackTrace();
                    ch = -1;
                }
                if (ch < 32)  // Control character or EOF terminates loop
                    break;
                command.append((char) ch);
                expected--;
            }

            // Close the socket now that we are done with it
            try {
                socket.close();
            } catch (IOException e) {
                ;
            }

            // Match against our command string
            boolean match = command.toString().equals(shutdown);
            if (match) {
                break;
            } else
                System.err.println("StandardServer.await: Invalid command '" +  command.toString() + "' received");
        }

        // Close the server socket and return
        try {
            serverSocket.close();
        } catch (IOException e) {
            ;
        }
    }

  wait()函数的作用在Catalina类中已经有讲过,就是新开一个侦听端口,无限循环直至端口接收到关闭命令,则退出循环,关闭端口.

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
    lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);

    lifecycle.fireLifecycleEvent(STOP_EVENT, null);
    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
    lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);

}

  与start()类似.

Service
container和connector

  服务组件(service)可以有一个container和多个connector(目前你只用知道connector是接受http请求的,container是处理http请求的), 但所有的connector都会与这一个container关联.
  来看看提供的StandardService类

public final class StandardService
    implements Lifecycle, Service {

    /**
     * The set of Connectors associated with this Service.
     */
    private Connector connectors[] = new Connector[0];

    /**
     * The Container associated with this Service.
     */
    private Container container = null;
    
    /**
     * The <code>Server</code> that owns this Service, if any.
     * 这个service属于哪个server
     */
    private Server server = null;
}

  StandardService中包含设置container,添加删除container的代码,需要注意的是container包含connector中,所以在设置container或者设置connector时,都需要更新对应的另外一个对象的内容。

 public void setContainer(Container container) {

    //解除老container与service的关系,---------并调用oldContainer.stop()---------
    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) {
            ;
        }
    }
    
    //注意下边这中同步写法................
    //改变每个connector的container
    synchronized (connectors) {
        for (int i = 0; i < connectors.length; i++)
            connectors[i].setContainer(this.container);
    }
    //看这里,老Container.stop()
    if (started && (oldContainer != null) &&
        (oldContainer instanceof Lifecycle)) {
        try {
            ((Lifecycle) oldContainer).stop();
        } catch (LifecycleException e) {
            ;
        }
    }
    // Report this property change to interested listeners
    support.firePropertyChange("container", oldContainer, this.container);
}

  就像上面展示的,注意两点:1. 解除老container与service的关系,并调用oldContainer.stop();2. 修改每个container的container(包含在同步代码块中)。
  类似的,添加时,注意设置connector的归属service以及container,移除connector时也要注意调用其stop()方法并解除其service和container。具体可查看源码

initialize()/start()/stop()/
    public void initialize()
    throws LifecycleException {
        if (initialized)
            throw new LifecycleException (
                sm.getString("standardService.initialize.initialized"));
        initialized = true;

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

  initialized变量防止重复初始化,并调用每个connector的initialize()方法。container无需初始化,后续后继续分析connector和container。

public void start() throws LifecycleException {
    // Validate and update our current component state
    if (started) {
        throw new LifecycleException
            (sm.getString("standardService.start.started"));
    }

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);

    System.out.println
        (sm.getString("standardService.start.name", this.name));
    lifecycle.fireLifecycleEvent(START_EVENT, null);
    started = true;
    // Start our defined Container first
    if (container != null) {
        synchronized (container) {
            if (container instanceof Lifecycle) {
                ((Lifecycle) container).start();
            }
        }
    }
    // Start our defined Connectors second
    synchronized (connectors) {
        for (int i = 0; i < connectors.length; i++) {
            if (connectors[i] instanceof Lifecycle)
                ((Lifecycle) connectors[i]).start();
        }
    }

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}

  调用每个connector和container的start()方法。
  stop()方法类似,就不展示了。

观察者模式

  上面代码中看到的lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); lifecycle.fireLifecycleEvent(STOP_EVENT, null);在Tomcat源码中非常常见,是Tomcat用来控制组件生命周期的一种手段。
  用通俗的比喻来说,就是当前的server带着一群小弟(Listener, 也叫observer), 当大哥server要进行stop操作时,操作之前,先吼一嗓子(lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);), 所有的小弟都会听到,并且做一些准备工作,然后又吼一嗓子开始干活了(lifecycle.fireLifecycleEvent(STOP_EVENT, null);), 所有小弟开始干正事了,然后大哥server也开始干正事了,完事后,大哥server也要和小弟通报一声(lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);), 小弟们都知道了,开始各自收拾东西。
  上面是一个形象的例子,具体看观察者模式的实现,可查看这个观察者模式

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值