/**
* Process the specified Request, and generate the corresponding Response,
* according to the design of this particular Container.
*
* @param request Request to be processed
* @param response Response to be produced
*
* @exception IOException if an input/output error occurred while
* processing
* @exception ServletException if a ServletException was thrown
* while processing this request
*/
public void invoke(Request request, Response response)
throws IOException, ServletException;
在invoke方法中,容器加载servlet类、调用service方法、管理session、记录错误信息日志等等。
使用对象池来降低复杂对象的创建开销。
*HTTP1.1新特性
public void run() {
ServerSocket serverSocket = null;
int port = 8080;
try {
serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
while (!stopped) {
// Accept the next incoming connection from the server socket
Socket socket = null;
try {
socket = serverSocket.accept();
} catch (Exception e) {
continue;
}
// Hand this socket off to an HttpProcessor
HttpProcessor processor = new HttpProcessor(this);
processor.process(socket);
}
}
HttpProcessor类的process方法在第三章中是同步方法。因此,它的run方法等待直到process方法处理结束才接收下一个请求。在本章,默认的连接器的HttpProcessor类实现了Runnable接口,因此每一个HttpProcessor实例都运行在自己的线程中,我们称为“processor线程”
Lifecycle接口的start和stop方法
/**
* Prepare for the beginning of active use of the public methods of this
* component. This method should be called before any of the public
* methods of this component are utilized. It should also send a
* LifecycleEvent of type START_EVENT to any registered listeners.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
public void start() throws LifecycleException;
/**
* Gracefully terminate the active use of the public methods of this
* component. This method should be the last one called on a given
* instance of this component. It should also send a LifecycleEvent
* of type STOP_EVENT to any registered listeners.
*
* @exception LifecycleException if this component detects a fatal error
* that needs to be reported
*/
public void stop() throws LifecycleException;
/**
* 判断HttpProcessor组件是否启动
*/
private boolean started = false;
/**
* Start the background thread we will use for request processing.
*
* @exception LifecycleException if a fatal startup error occurs
*/
public void start() throws LifecycleException {
if (started)
throw new LifecycleException
(sm.getString("httpProcessor.alreadyStarted"));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
threadStart();
}
/**
* 开启后台处理线程
*/
private void threadStart() {
log(sm.getString("httpProcessor.starting"));
thread = new Thread(this, threadName);
thread.setDaemon(true);
thread.start();
if (debug >= 1)
log(" Background thread has been started");
}
HttpProcessor的run方法的while循环执行流程:获得一个socket,处理它,调用connector的recycle(回收)方法把当前的HttpProcessor实例压回栈中。注意到while循环中停止到await方法处,await方法掌握着“processor thread”的控制流,直到它从HttpConnetor获得到一个新的socket对象。换句话说,直到HttpConnetor类调用HttpProcessor实例的assign方法。
/* * The background thread that listens for incoming TCP/IP connections and
* hands them off to an appropriate processor.
*/
public void run() {
// Process requests until we receive a shutdown signal
while (!stopped) {
// Wait for the next socket to be assigned
Socket socket = await();
if (socket == null)
continue;
// Process the request from this socket
try {
process(socket);
} catch (Throwable t) {
log("process.invoke", t);
}
// Finish up this request
connector.recycle(this);
}
// Tell threadStop() we have shut ourselves down successfully
synchronized (threadSync) {
threadSync.notifyAll();
}
}
将调用完的HttpProcessor实例压回栈中的代码实现:
/**
* Process an incoming TCP/IP connection on the specified socket. Any
* exception that occurs during processing must be logged and swallowed.
* <b>NOTE</b>: This method is called from our Connector's thread. We
* must assign it to our own thread so that multiple simultaneous
* requests can be handled.
*
* @param socket TCP socket to process
*/
synchronized void assign(Socket socket) {
// Wait for the Processor to get the previous Socket
while (available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// Store the newly available Socket and notify our thread
this.socket = socket;
available = true;
notifyAll();
if ((debug >= 1) && (socket != null))
log(" An incoming request is being assigned");
}
HttpProcessor线程调用的await方法:
/**
* Await a newly assigned Socket from our Connector, or <code>null</code>
* if we are supposed to shut down.
*/
private synchronized Socket await() {
// Wait for the Connector to provide a new Socket
while (!available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// Notify the Connector that we have received this Socket
Socket socket = this.socket;
available = false;
notifyAll();
if ((debug >= 1) && (socket != null))
log(" The incoming request has been awaited");
return (socket);
}
初始时,当“processor thread”刚启动时,available为false,即还没有可用的socket。因此线程在while循环中等待,直到其他线程调用notify或者notifyAll方法。也就是说,调用wait方法导致“processor thread”暂停直到“connector thread”对这个HttpProcessor实例调用notifyAll方法。当一个新的socket被分配,“connector thread”调用HttpProcessor的assign方法。avilable置为true,唤醒“processor thread”。