在Bootstrap类中
public final class Bootstrap {
public static void main(String[] args) {
System.setProperty("catalina.base", System.getProperty("user.dir"));
Connector connector = new HttpConnector();
Wrapper wrapper1 = new StandardWrapper();//表示一个servlet容器
wrapper1.setName("Primitive");
wrapper1.setServletClass("PrimitiveServlet");
Wrapper wrapper2 = new StandardWrapper();
wrapper2.setName("Modern");
wrapper2.setServletClass("ModernServlet");
Context context = new StandardContext();
// StandardContext's start method adds a default mapper
context.setPath("/app1");
context.setDocBase("app1");
context.addChild(wrapper1);
context.addChild(wrapper2);
LifecycleListener listener = new SimpleContextConfig();
((Lifecycle) context).addLifecycleListener(listener);
Host host = new StandardHost();
host.addChild(context);
host.setName("localhost");
host.setAppBase("webapps");
Loader loader = new WebappLoader();
context.setLoader(loader);
// context.addServletMapping(pattern, name);
context.addServletMapping("/Primitive", "Primitive");
context.addServletMapping("/Modern", "Modern");
Engine engine = new StandardEngine();
engine.addChild(host);
engine.setDefaultHost("localhost");
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 {
//最终调用services[i].initialize(); 该方法用于初始化添加到其中的所有连接器.
//那么连接器要初始化什么东西呢?-->打开socket开始监听
server.initialize();
//该方法最后会启动container,connectors。利用for启动多个。
//那么启动什么东西呢?-->每一个组件启动都会发送相关事件,
((Lifecycle) server).start();
server.await();//等待关闭命令--这里关闭
// the program waits until the await method returns,
// i.e. until a shutdown command is received.
}
catch (LifecycleException e) {
e.printStackTrace(System.out);
}
}
//这里开始关闭啦 !
if (server instanceof Lifecycle) {
try {
((Lifecycle) server).stop();
}
catch (LifecycleException e) {
e.printStackTrace(System.out);
}
}
}
}
看看StandardServer#await()方法
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) {
;
}
}
先调用StandardServer的stop()方法 关闭与它关联的组件
StandardServer
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();//关闭所有service,即调用StandardService的stop()
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
}
复制代码
StandardService
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[i] instanceof Lifecycle)
((Lifecycle) connectors[i]).stop();//1关闭连接器
}
}
// Stop our defined Container second
if (container != null) {
synchronized (container) {
if (container instanceof Lifecycle) {
((Lifecycle) container).stop();//2关闭容器
}
}
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
}复制代码
#1:for循环关闭所有连接器。(即调用connector的stop方法)如下
HttpConnector
public void stop() throws LifecycleException {
// Validate and update our current state
if (!started)
throw new LifecycleException(sm.getString("httpConnector.notStarted"));
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
// Gracefully shut down all processors we have created
for (int i = created.size() - 1; i >= 0; i--) {
HttpProcessor processor = (HttpProcessor) created.elementAt(i);
if (processor instanceof Lifecycle) {
try {
((Lifecycle) processor).stop();//1)
} catch (LifecycleException e) {
log("HttpConnector.stop", e);
}
}
}
synchronized (threadSync) {
// Close the server socket we were using
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
}
}
// Stop our background thread
threadStop();
}
serverSocket = null;
}
1)关闭所有processor。代码如下
public void stop() throws LifecycleException {
if (!started)
throw new LifecycleException(sm.getString("httpProcessor.notStarted"));
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
threadStop();
}
private void threadStop() {
log(sm.getString("httpProcessor.stopping"));
stopped = true;
assign(null);
if (status != Constants.PROCESSOR_IDLE) {
// Only wait if the processor is actually processing a command
synchronized (threadSync) {
try {
threadSync.wait(5000);
} catch (InterruptedException e) {
;
}
}
}
thread = null;
}
复制代码
#2:关闭container组件。调用其stop方法。
StandardContext复制代码
public synchronized void stop() throws LifecycleException {
// Validate and update our current component state
if (!started)
throw new LifecycleException(sm.getString("containerBase.notStarted", logName()));
if (debug >= 1)
log("Stopping");
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
// Mark this application as unavailable while we shut down
setAvailable(false);//服务设为不可用
// Binding thread
ClassLoader oldCCL = bindThread();
// Stop our filters
filterStop();//关闭过滤器
// Finalize our character set mapper
setCharsetMapper(null);
if ((manager != null) && (manager instanceof Lifecycle)) {
((Lifecycle) manager).stop();//关闭管理器
}
// Normal container shutdown processing
if (debug >= 1)
log("Processing standard container shutdown");
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
try {
// Stop the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).stop();//关闭管道
}
// Stop our child containers, if any
Container children[] = findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Lifecycle)
((Lifecycle) children[i]).stop();//关闭所有子容器
}
// Stop our Mappers, if any
Mapper mappers[] = findMappers();
for (int i = 0; i < mappers.length; i++) {
if (mappers[(mappers.length-1)-i] instanceof Lifecycle)
((Lifecycle) mappers[(mappers.length-1)-i]).stop();//关闭映射器
}
// Stop our application listeners
listenerStop();//关闭监听器
// Stop our subordinate components, if any
if (resources != null) {
if (resources instanceof Lifecycle) {
((Lifecycle) resources).stop();
} else if (resources instanceof ProxyDirContext) {
DirContext dirContext =
((ProxyDirContext) resources).getDirContext();
if (dirContext != null) {
if (debug >= 1) {
log("Releasing document base " + docBase);
}
if (dirContext instanceof BaseDirContext) {
((BaseDirContext) dirContext).release();
if ((dirContext instanceof WARDirContext)
|| (dirContext instanceof FileDirContext)) {
resources = null;
}
} else {
log("Cannot release " + resources);
}
}
}
}
if ((realm != null) && (realm instanceof Lifecycle)) {
((Lifecycle) realm).stop();
}
if ((cluster != null) && (cluster instanceof Lifecycle)) {
((Lifecycle) cluster).stop();
}
if ((logger != null) && (logger instanceof Lifecycle)) {
((Lifecycle) logger).stop();
}
if ((loader != null) && (loader instanceof Lifecycle)) {
((Lifecycle) loader).stop();
}
} finally {
// Unbinding thread
unbindThread(oldCCL);
}
// Reset application context
context = null;
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
if (debug >= 1)
log("Stopping complete");
}复制代码