知识库--tomcat+StandardService

来源:互联网 发布:js 将a标签隐藏 编辑:程序博客网 时间:2024/06/16 03:07

StandardServer

The org.apache.catalina.core.StandardServer class is the standard implementation of Server. We’re particularly interested in the shutdown mechanism offered by this class, which is also the most important feature in this class. Many methods are related to the storing of the server configuration into a new server.xml file, but they will not be discussed here. For those interested, these methods are not difficult to understand, though.

Four methods are related to the lifecycle of the StandardServer: initialize, start, stop, and await. Just like any other components, you initialize and start a server. You then call the await method followed by the stop method. The await method does not return until it receives a shutdown command on port 8085. When the await method returns, the stop method is run to stop all the sub-components.

The initialize Method

The initialize method is used to initialize services added to the Server instance.

    public void initialize()throws LifecycleException{        if(initialized){            throw new LifecycleException(...);        }        initialized = true;        //Initialize our defined Services        for(int i = 0;i<service.length;i++){            services[i].initialize();        }    }

The stop method does not reset the value of initialized, so that if the server is stopped and started again, its initialized method is not called again.

The start Method
The implementation of this method in StandardServer starts all services which in turn starts all other components, such as the connector(s) and the container.

    public void start() throws lifecycleException{        if(started)            throw new LifecycleException(...);        //Notify our interested LifecycleListeners        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT,null);        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);        }    }

The start method employs the start boolean variable to prevent a server from being started twice. The stop method resets this variable;

The stop Method

    public void stop() throws LifecycleException{        //validate and update our current component state        if(!started)            throw new LifecycleException("standardServer.stop.notStarted");        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT,null);        lifecycle.fireLifecycleEvent(STOP_EVENT,null);        started = false;//reset        //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);    }

The await method
The await method is responsible for the stop mechanism of the whole Tomcat deployment.

    //wait until a proper shutdown command is received, then return    public void wait(){        //Set up a server socket to wait on        ServerSocket serverSocekt = 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.lenght()){                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){;}    }

The await method creates a ServerSocket object that waits on port 8085 and then calls its accept method in a while loop. The accept method will only return if there is an incoming message on the designated port (8085). Each message will then be matched against the shutdown string. If it matches, control breaks out of the while loop and the SocketServer is closed. If it does not match, control stays in the while loop waiting for another message.

0 0