4.1 Tomcat学习(Tomcat默认连接器)

来源:互联网 发布:网络通信工程师考试 编辑:程序博客网 时间:2024/05/21 18:00

Tomcat默认连接器必须实现org.apache.catalina.Connector接口,接口中最重要是以下四个方法:

1、setContainer()用于将连接器和某个servlet容器相关联。

2、getContainer()返回与当前连接器相关联的容器。

3、createRequest()方法会为引入的HTTP请求创建request对象

4、createResponse()会创建一个response对象

以下是Tomcat默认连接器的UML简图:


HttpConnector类作用:

1、通过工厂类(ServerSocketFactory或DefaultServerSocketFactory)创建服务套接字

//HttpConnector类的open()方法
private ServerSocket open()    throws IOException, KeyStoreException, NoSuchAlgorithmException,           CertificateException, UnrecoverableKeyException,           KeyManagementException    {        ServerSocketFactory factory = getFactory();        if (address == null) {            log(sm.getString("httpConnector.allAddresses"));            try {                return (factory.createSocket(port, acceptCount));            } catch (BindException be) {                throw new BindException(be.getMessage() + ":" + port);            }        }        try {            InetAddress is = InetAddress.getByName(address);            log(sm.getString("httpConnector.anAddress", address));            try {                return (factory.createSocket(port, acceptCount, is));            } catch (BindException be) {                throw new BindException(be.getMessage() + ":" + address +                                        ":" + port);            }        } catch (Exception e) {            log(sm.getString("httpConnector.noAddress", address));            try {                return (factory.createSocket(port, acceptCount));            } catch (BindException be) {                throw new BindException(be.getMessage() + ":" + port);            }        }    }
2、维护HttpProcessor实例,避免每次都为新的Http请求创建HttpProcessor实例,减少系统开销。

private Stack processors = new Stack()//用一个栈来存放若干个HttpProcessor实例,需要时便从栈中弹出一个HttpProcessor,使用完以后由从新压入栈内。
HttpProcessor类的作用

在上一节中,HttpProcessor没有实现Runnable,因此当有多个Http请求同时到达服务器时,必须每个请求依次处理
以下是上一节HttpConnector类的部分代码:

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) {      Socket socket = null;      try {        socket = serverSocket.accept();      }      catch (Exception e) {        continue;      }      HttpProcessor processor = new HttpProcessor(this);      processor.process(socket);//HttpProcessor没有实现Runnable,所以processor.process(socket)是运行在当前线程    }  }
在Tomcat默认连器中,HttpProcessor类实现类java.iang.Runnable接口,因此当有多个请求同时访问服务器的时候,HttpConnector会为每个请求新起一个线程用以执行HttpProcessor。以下是HttpProcessor类的run()方法。

public void run() {        while (!stopped) {            Socket socket = await();//获取套接字            if (socket == null)                continue;            try {                process(socket);//进行处理            } catch (Throwable t) {                log("process.invoke", t);            }            connector.recycle(this);//将当前HttpProcessor实例压回processors桟中        }        synchronized (threadSync) {            threadSync.notifyAll();        }    }
HttpConnector和HttpProcessor分在不同的线程中运行,因此需要保证先执行HttpConnector类中processor.assign(socket)方法,将socket传给传递给HttpProcessor;在没有传递socket之前,HttpProcessor线程必须处于等待状态。当socket传递给HttpProcessor后,HttpProcessor线程再开始执行。具体流程如下:




0 0