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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值