其实tomcat在哪个类中监听请求的代码很容易找到:
在org.apache.tomcat.util.net.JIoEndpoint$Acceptor#run()中的这么一句:
Socket socket = serverSocketFactory.acceptSocket(serverSocket);
可是ServerSocketFactory是个抽象类,我还是很想知道整个过程的来龙去脉的。
那就要还是从初始化开始,当Tomcat的HTTP Connector初始化,会org.apache.coyote.http11.Http11Protocol调用它的init()方法。
在这个init()方法中,又调用了org.apache.tomcat.util.net.JIoEndpoint#init(),代码如下:
现在已经知道了文章最初提到的serverSocketFactory引用的是一个DefaultServerSocketFactory类的对象。并且在这里创建了一个ServerSocket对象。
当Tomcat初始化完毕执行一些列开启服务的动作时,HTTP Connector也会执行它的start()方法,然后会调用Http11Protocol的start()方法,最后程序会执行到JIoEndpoint#start(),下面来看一下:
这样,就开启了一个Acceptor线程,接下来看一看这个线程做了什么东西。
至此,Tomcat开启了一个端口进行请求的监听。
在org.apache.tomcat.util.net.JIoEndpoint$Acceptor#run()中的这么一句:
Socket socket = serverSocketFactory.acceptSocket(serverSocket);
可是ServerSocketFactory是个抽象类,我还是很想知道整个过程的来龙去脉的。
那就要还是从初始化开始,当Tomcat的HTTP Connector初始化,会org.apache.coyote.http11.Http11Protocol调用它的init()方法。
在这个init()方法中,又调用了org.apache.tomcat.util.net.JIoEndpoint#init(),代码如下:
- public void init() throws Exception {
- if (initialized)
- return;
- // acceptor线程的数量
- if (acceptorThreadCount == 0) {
- acceptorThreadCount = 1;
- }
- // 返回DefaultServerSocketFactory类对象做为ServerSocketFactory的实例
- if (serverSocketFactory == null) {
- serverSocketFactory = ServerSocketFactory.getDefault();
- }
- // 创建ServerSocket
- if (serverSocket == null) {
- try {
- if (address == null) {
- serverSocket = serverSocketFactory.createSocket(port, backlog);
- } else {
- serverSocket = serverSocketFactory.createSocket(port, backlog, address);
- }
- } catch (BindException be) {
- if (address == null)
- throw new BindException(be.getMessage() + "<null>:" + port);
- else
- throw new BindException(be.getMessage() + " " + address.toString() + ":" + port);
- }
- }
- initialized = true;
- }
现在已经知道了文章最初提到的serverSocketFactory引用的是一个DefaultServerSocketFactory类的对象。并且在这里创建了一个ServerSocket对象。
当Tomcat初始化完毕执行一些列开启服务的动作时,HTTP Connector也会执行它的start()方法,然后会调用Http11Protocol的start()方法,最后程序会执行到JIoEndpoint#start(),下面来看一下:
- public void start() throws Exception {
- if (!initialized) {
- init();
- }
- if (!running) {
- running = true;
- paused = false;
- // 先初始化一些Worker
- if (executor == null) {
- workers = new WorkerStack(maxThreads);
- }
- // 开启Acceptor线程,默认只开启一个Acceptor线程,见JIoEndpoint#init()。
- for (int i = 0; i < acceptorThreadCount; i++) {
- Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);
- acceptorThread.setPriority(threadPriority);
- acceptorThread.setDaemon(daemon);
- acceptorThread.start();
- }
- }
- }
这样,就开启了一个Acceptor线程,接下来看一看这个线程做了什么东西。
- public void run() {
- while (running) {
- while (paused) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- }
- try {
- // 开始监听端口
- Socket socket = serverSocketFactory.acceptSocket(serverSocket);
- // 初始化Socket
- serverSocketFactory.initSocket(socket);
- if (!processSocket(socket)) {
- try {
- socket.close();
- } catch (IOException e) {
- }
- }
- } catch (IOException x) {
- if (running)
- log.error(sm.getString("endpoint.accept.fail"), x);
- } catch (Throwable t) {
- log.error(sm.getString("endpoint.accept.fail"), t);
- }
- }
- }
至此,Tomcat开启了一个端口进行请求的监听。