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.initialize();
}
}
start()方法用于启动Server组件,在StandardServer类的start()方法的实现中,它会启动其所有的Service组件,这些Service组件它们逐个启动所有其他的组件,如连接器组件和servlet容器。
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);
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// Start our defined Services
synchronized (services) {
for (int i = 0; i < services.length; i++) {
if (services instanceof Lifecycle)
((Lifecycle) services).start();
}
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
stop()方法用于关闭Server组件
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 instanceof Lifecycle)
((Lifecycle) services).stop();
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
}
await()方法负责停止整个tomcat部署的机制
/**
* Wait until a proper shutdown command is received, then return.
*/
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) {
;
}
}
await()方法创建一个ServerSocket对象,监听8085端口,并在while循环中调用它的accept()方法,挡在指定端口上接收到消息时,才会从accept()方法中返回,然后将接收到的消息与关闭命令的字符串相比较,相同的话就跳出while循环,关闭ServerSocket,否则会再次循环,继续等待消息。
Service组件是org.apache.catalina.Service接口的实例,一个Service组件可以有一个servlet容器和多个连接器实例,可以自由地把连接器实例添加到Service组件中,所有的连接器都会与该servlet容器相关联
下面是Service接口的定义
public void removeConnector(Connector connector) {
synchronized (connectors) {
int j = -1;
for (int i = 0; i < connectors.length; i++) {
if (connector == connectors) {
j = i;
break;
}
}
if (j < 0)
return;
if (started && (connectors[j] instanceof Lifecycle)) {
try {
((Lifecycle) connectors[j]).stop();
} catch (LifecycleException e) {
;
}
}
connectors[j].setContainer(null);
connector.setService(null);
int k = 0;
Connector results[] = new Connector[connectors.length - 1];
for (int i = 0; i < connectors.length; i++) {
if (i != j)
results[k++] = connectors;
}
connectors = results;
// Report this property change to interested listeners
support.firePropertyChange("connector", connector, null);
}
}
与生命周期相关的方法包括从Lifecycle接口中实现的start()方法和stop()方法,在加上initialize()方法,其中initialize()方法会调用该Service组件中所有连接器的上initialize()方法:
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.initialize();
}
}
}
start()方法负责启动被添加到该Service组件中的连接器和servlet容器:
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 instanceof Lifecycle)
((Lifecycle) connectors).start();
}
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
stop()方法用于关闭与该Service组件相关联的servlet容器和所有连接器
public void stop() throws LifecycleException {
// Validate and update our current component state
if (!started) {
throw new LifecycleException
(sm.getString("standardService.stop.notStarted"));
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
System.out.println
(sm.getString("standardService.stop.name", this.name));
started = false;
// Stop our defined Connectors first
synchronized (connectors) {
for (int i = 0; i < connectors.length; i++) {
if (connectors instanceof Lifecycle)
((Lifecycle) connectors).stop();
}
}
// Stop our defined Container second
if (container != null) {
synchronized (container) {
if (container instanceof Lifecycle) {
((Lifecycle) container).stop();
}
}
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
}
在前面文章的应用程序中,通过按某个键或强制中断的方式关闭servlet容器,Stopper类提供了一种更优雅的方式来关闭Catalina服务器;此外,它也保证了所有的生命周期组件的stop()方法都能够调用。
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.");
}
}
}