目录
简介
第四章相比与第三章最大的区别在于HttpConnector和HttpProcessor是一对多的关系,这使得这个版本的服务器可以同时处理多个http请求。
- Bootstrap
- HttpConnector:
- 负责创建Request、Response和ServerSocket
- 连接器和容器一对一关系,连接器和处理器一对多关系
- 实现LifeCycle接口,在第六章详细介绍,新增部分
- HttpProcessor
- HttpRequestImpl
- HttpResponseImpl
- SimpleContainer
核心源码
后面的章节组件功能会逐渐复杂起来,因此只会挑出一部分源码来进行注释讲解
Bootstrap
public final class Bootstrap {
public static void main(String[] args) {
HttpConnector connector = new HttpConnector();
SimpleContainer container = new SimpleContainer();
connector.setContainer(container);
try {
// 初始化HttpConnector
connector.initialize();
// 启动HttpConnector
connector.start();
// make the application wait until we press any key.
System.in.read();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
HttpConnector
public class HttpConnector implements Connector, Lifecycle, Runnable {
// HttpConnector是否初始化
private boolean initialized = false;
// 简单的容器,为下一章做铺垫
protected Container container = null;
// HttpConnector是否启动
private boolean started = false;
// HttpConnector是否停止
private boolean stopped = false;
// 后台线程,用来执行HttpConnector的run方法
private Thread thread = null;
// 后台线程名称
private String threadName = null;
// 锁
private Object threadSync = new Object();
// 请求对象
private HttpRequestImpl request = null;
// 响应对象
private HttpResponseImpl response = null;
// 已被创建但没有被使用的HttpProcessor的集合
private Stack processors = new Stack();
// 已被创建的HttpProcessor
private Vector created = new Vector();
// 最小HttpProcessor数量
protected int minProcessors = 5;
// 最大HttpProcessor数量
private int maxProcessors = 20;
// 当前已创建的HttpProcessor的数量
private int curProcessors = 0;
// 初始化HttpConnector(ServerSocket在此创建)
public void initialize() throws LifecycleException {
if (initialized) {
throw new LifecycleException (sm.getString("httpConnector.alreadyInitialized"));
}
this.initialized=true;
Exception eRethrow = null;
// open方法内部使用了工厂模式创建了ServerSocket
try {
serverSocket = open();
} catch (Exception e) {
// 此处省略
...
}
if ( eRethrow != null )
throw new LifecycleException(threadName + ".open", eRethrow);
}
// 开始处理Http请求
public void start() throws LifecycleException {
if (started)
throw new LifecycleException
(sm.getString("httpConnector.alreadyStarted"));
threadName = "HttpConnector[" + port + "]";
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// 启动后台线程(执行run方法)
threadStart();
// 创建指定的最小数量的HttpProcessor
while (curProcessors < minProcessors) {
if ((maxProcessors > 0) && (curProcessors >= maxProcessors))
break;
// new一个新的HttpProcessor
HttpProcessor processor = newProcessor();
// todo: 疑问, newProcessor会启动创建的Processor啊
// 初始化的HttpProcessor先放入未使用的HttpProcessor集合中(回收)
recycle(processor);
}
}
private void threadStart() {
log(sm.getString("httpConnector.starting"));
thread = new Thread(this, threadName);
thread.setDaemon(true);
thread.start();
}
void recycle(HttpProcessor processor) {
processors.push(processor);
}
// new一个HttpProcessor, 没报错的情况下一定会new一个新的HttpProcessor
//(区别于createProcessor()方法)
private HttpProcessor newProcessor() {
HttpProcessor processor = new HttpProcessor(this, curProcessors++);
if (processor instanceof Lifecycle) {
try {
((Lifecycle) processor).start();
} catch (LifecycleException e) {
log("newProcessor", e);
return (null);
}
}
// 放入已创建的HttpProcessor集合中
created.addElement(processor);
return (processor);
}
// 后台线程启动后执行该方法
public void run() {
// 循环,直到收到shutdown指令
while (!stopped) {
Socket socket = null;
try {
//
socket = serverSocket.accept();
if (connectionTimeout > 0)
socket.setSoTimeout(connectionTimeout);
socket.setTcpNoDelay(tcpNoDelay);
} catch (AccessControlException ace) {
// 省略
...
continue;
}
// 给一个请求创建一个HttpProcessor,
HttpProcessor processor = createProcessor();
if (processor == null) {
try {
log(sm.getString("httpConnector.noProcessor"));
socket.close();
} catch (IOException e) {
;
}
continue;
}
// 将socket传入HttpProcessor线程
processor.assign(socket);
}
synchronized (threadSync) {
threadSync.notifyAll();
}
}
// 返回一个可用的HttpProcessor,如果HttpProcessor数量达到最大值且都在使用中,返回null
// 没有可用的HttpProcessor时会忽略客户端的请求
private HttpProcessor createProcessor() {
synchronized (processors) {
if (processors.size() > 0) {
return ((HttpProcessor) processors.pop());
}
if ((maxProcessors > 0) && (curProcessors < maxProcessors)) {
return (newProcessor());
} else {
if (maxProcessors < 0) {
return (newProcessor());
} else {
return (null);
}
}
}
}
/**
* Create (or allocate) and return a Request object suitable for
* specifying the contents of a Request to the responsible Container.
*/
public Request createRequest() {
HttpRequestImpl request = new HttpRequestImpl();
request.setConnector(this);
return (request);
}
/**
* Create (or allocate) and return a Response object suitable for
* receiving the contents of a Response from the responsible Container.
*/
public Response createResponse() {
HttpResponseImpl response = new HttpResponseImpl();
response.setConnector(this);
return (response);
}
// 其它省略
...
}
HttpConnector主要工作流程:
- 创建服务器套接字;
- 池化思想:维护了HttpProcessor对象池,一个HttpProcessor负责一个http请求;
- 从对象池获取一个可用的HttpProcessor,将Socket传给HttpProcessor,让HttpProcessor处理具体的请求;
HttpProcessor
final class HttpProcessor implements Lifecycle, Runnable {
public HttpProcessor(HttpConnector connector, int id) {
super();
this.connector = connector;
this.debug = connector.getDebug();
this.id = id;
this.proxyName = connector.getProxyName();
this.proxyPort = connector.getProxyPort();
this.request = (HttpRequestImpl) connector.createRequest();
this.response = (HttpResponseImpl) connector.createResponse();
this.serverPort = connector.getPort();
this.threadName =
"HttpProcessor[" + connector.getPort() + "][" + id + "]";
}
// 是否有可用的Socket,默认为false
private boolean available = false;
// 和HttpProcessor关联的HttpConnector
private HttpConnector connector = null;
private HttpRequestImpl request = null;
private HttpResponseImpl response = null;
private Socket socket = null;
// HttpProcessor是否启动
private boolean started = false;
// 后台线程
private Thread thread = null;
// 后台线程是否被停止
private boolean stopped = false;
// 后台线程名称
private String threadName = null;
// 锁对象
private Object threadSync = new Object();
private synchronized Socket await() {
// 等待HttpConnector提供一个新的Socket
while (!available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// 将HttpConnector传入的Socket赋值给成员变量
Socket socket = this.socket;
available = false;
// 通知HttpConnector我们已经接收到了这个Socket
notifyAll();
if ((debug >= 1) && (socket != null))
log(" The incoming request has been awaited");
return (socket);
}
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");
}
public void run() {
while (!stopped) {
// 阻塞,等待HttpConnector传入Socket
// 在HttpConnector中调用processor.assign(socket),传入待处理请求的Socket后
// await方法才返回,后续调用process去处理请求
// 这里可以看出,只有调用了assign方法的HttpProcessor才被视为已使用的
// 而刚启动的HttpProcessor不能被视为已使用的
// 所以启动HttpProcessor时调用recycle方法,就没有什么问题了
Socket socket = await();
if (socket == null)
continue;
try {
// 处理请求
process(socket);
} catch (Throwable t) {
log("process.invoke", t);
}
// 处理完请求后,回收当前的HttpProcessor
connector.recycle(this);
}
// Tell threadStop() we have shut ourselves down successfully
synchronized (threadSync) {
threadSync.notifyAll();
}
}
// 启动后台线程
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("httpConnector.starting"));
// 传入HttpConnector,启动后调用run方法
thread = new Thread(this, threadName);
thread.setDaemon(true);
thread.start();
}
// 停止后台线程
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;
}
// 构造request和response请求
private void process(Socket socket) {
// 1.解析连接
...
// 2.解析请求
...
// 3.解析请求头
...
// 将构造好的request和response对象传给container,调用container的invoke方法
try {
// 省略
...
if (ok) {
connector.getContainer().invoke(request, response);
}
} catch (Exception e) {
// 省略
...
}
}
}
SimpleContainer
public class SimpleContainer implements Container {
public static final String WEB_ROOT =
System.getProperty("user.dir") + File.separator + "webroot";
public SimpleContainer() {
}
public void invoke(Request request, Response response)
throws IOException, ServletException {
String servletName = ( (HttpServletRequest) request).getRequestURI();
servletName = servletName.substring(servletName.lastIndexOf("/") + 1);
URLClassLoader loader = null;
try {
URL[] urls = new URL[1];
URLStreamHandler streamHandler = null;
File classPath = new File(WEB_ROOT);
String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString() ;
urls[0] = new URL(null, repository, streamHandler);
loader = new URLClassLoader(urls);
}
catch (IOException e) {
System.out.println(e.toString() );
}
Class myClass = null;
try {
myClass = loader.loadClass(servletName);
}
catch (ClassNotFoundException e) {
System.out.println(e.toString());
}
Servlet servlet = null;
try {
servlet = (Servlet) myClass.newInstance();
servlet.service((HttpServletRequest) request, (HttpServletResponse) response);
}
catch (Exception e) {
System.out.println(e.toString());
}
catch (Throwable e) {
System.out.println(e.toString());
}
}
// 省略其他未实现的方法
...
}
UML类图
图片从《How Tomcat Works》一书中截取