tomcat《一》

 

 

 

 

 

 

验证:Tomcat猜想
是不是由一个个Socket组装的Servlet

 

 

 

     */
    protected class Acceptor extends AbstractEndpoint.Acceptor {

        @Override
        public void run() {

            int errorDelay = 0;

            // Loop until we receive a shutdown command
            while (running) {//判断云运行状态

                // Loop if endpoint is paused
                while (paused && running) {
                    state = AcceptorState.PAUSED;
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }

                if (!running) {
                    break;
                }
                state = AcceptorState.RUNNING;

                try {
                    //if we have reached max connections, wait
                    countUpOrAwaitConnection();

                    Socket socket = null;
                    try {
                        // Accept the next incoming connection from the server
                        // socket    一个工厂循环创建socket
                        socket = serverSocketFactory.acceptSocket(serverSocket);
                    } catch (IOException ioe) {
                        countDownConnection();
                        // Introduce delay if necessary
                        errorDelay = handleExceptionWithDelay(errorDelay);
                        // re-throw
                        throw ioe;
                    }
                    // Successful accept, reset the error delay
                    errorDelay = 0;

                    // Configure the socket
                    if (running && !paused && setSocketOptions(socket)) {
                        // Hand this socket off to an appropriate processor
                        if (!processSocket(socket)) {
                            countDownConnection();
                            // Close socket right away
                            closeSocket(socket);
                        }
                    } else {
                        countDownConnection();
                        // Close socket right away
                        closeSocket(socket);
                    }
                } catch (IOException x) {
                    if (running) {
                        log.error(sm.getString("endpoint.accept.fail"), x);
                    }
                } catch (NullPointerException npe) {
                    if (running) {
                        log.error(sm.getString("endpoint.accept.fail"), npe);
                    }
                } catch (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                    log.error(sm.getString("endpoint.accept.fail"), t);
                }
            }
            state = AcceptorState.ENDED;
        }
    }

 

   
public class DefaultServerSocketFactory implements ServerSocketFactory {

 @Override
    public ServerSocket createSocket (int port) throws IOException {
        return  new ServerSocket (port);
    }

    @Override
    public ServerSocket createSocket (int port, int backlog)
            throws IOException {
        return new ServerSocket (port, backlog);
    }

    @Override
    public ServerSocket createSocket (int port, int backlog,
            InetAddress ifAddress) throws IOException {
        return new ServerSocket (port, backlog, ifAddress);
    }
......

 

 

 

 

Tomcat架构猜想,server.xml中每一个标签对应一个类,
接下来先分析Contex到官网发现:
The Context element represents a web application, 
which is run within a particular virtual host. 
Each web application is based on a Web Application Archive (WAR) file, 
or a corresponding directory containing the corresponding unpacked contents
第一句可以发现一个Contetx就是一个web项目。
那么疑问来了,web是不是把一个个Servlet进行组装呢?

 

源码:
public class StandardContext extends ContainerBase implements Context, NotificationEmitter 
StandardContext 实现了Context重写的方法如下
 public boolean loadOnStartup(Container[] children) {
        TreeMap<Integer, ArrayList<Wrapper>> map = new TreeMap();

        for(int i = 0; i < children.length; ++i) {
            Wrapper wrapper = (Wrapper)children[i];
            int loadOnStartup = wrapper.getLoadOnStartup();
            if (loadOnStartup >= 0) {
                Integer key = loadOnStartup;
                ArrayList<Wrapper> list = (ArrayList)map.get(key);
                if (list == null) {
                    list = new ArrayList();
                    map.put(key, list);
                }

                list.add(wrapper);
            }
        }

 

Conetxt添加了servlet,但是StandContext里这个方法加载的是Wrapper.接下来看Wrapper是否是等于Servlet,源码中使用了包装器模式进行了加强

 

ContextConfig类的854行左右的这个方法
configureContext在990行左右的源码
      while(var31.hasNext()) {
            ServletDef servlet = (ServletDef)var31.next();
           //使用包装器的方法
            Wrapper wrapper = this.context.createWrapper();
          //使用包装器的方法把Servlet与Wrapper进行转化
              if (servlet.getLoadOnStartup() != null) {
                wrapper.setLoadOnStartup(servlet.getLoadOnStartup());
            }

            if (servlet.getEnabled() != null) {
            //使用包装器的方法把Servlet与Wrapper进行转化
                wrapper.setEnabled(servlet.getEnabled());
            }
            //使用包装器的方法把Servlet与Wrapper进行转化
            wrapper.setName(servlet.getServletName());
            Map<String, String> params = servlet.getParameterMap();
            var7 = params.entrySet().iterator();

            while(var7.hasNext()) {
                Entry<String, String> entry = (Entry)var7.next();
                //使用包装器的方法把Servlet与Wrapper进行转化
                wrapper.addInitParameter((String)entry.getKey(), (String)entry.getValue());
            }

            wrapper.setRunAs(servlet.getRunAs());
            Set<SecurityRoleRef> roleRefs = servlet.getSecurityRoleRefs();
            Iterator var33 = roleRefs.iterator();

            while(var33.hasNext()) {
                SecurityRoleRef roleRef = (SecurityRoleRef)var33.next();
                wrapper.addSecurityReference(roleRef.getName(), roleRef.getLink());
            }
          //使用包装器的方法把Servlet与Wrapper进行转化 
            wrapper.setServletClass(servlet.getServletClass());
            MultipartDef multipartdef = servlet.getMultipartDef();
            if (multipartdef != null) {
                if (multipartdef.getMaxFileSize() != null && multipartdef.getMaxRequestSize() != null && multipartdef.getFileSizeThreshold() != null) {
                    wrapper.setMultipartConfigElement(new MultipartConfigElement(multipartdef.getLocation(), Long.parseLong(multipartdef.getMaxFileSize()), Long.parseLong(multipartdef.getMaxRequestSize()), Integer.parseInt(multipartdef.getFileSizeThreshold())));
                } else {
                    wrapper.setMultipartConfigElement(new MultipartConfigElement(multipartdef.getLocation()));
                }
            }

            if (servlet.getAsyncSupported() != null) {
           //使用包装器的方法把Servlet与Wrapper进行转化 
                wrapper.setAsyncSupported(servlet.getAsyncSupported());
            }
       //使用包装器的方法把Servlet与Wrapper进行转化 
            wrapper.setOverridable(servlet.isOverridable());
  //使用包装器的方法把Servlet与Wrapper进行转化 最终添加
            this.context.addChild(wrapper);
        }

 

posted @ 2022-02-20 20:42  余生请多指教ANT  阅读(29)  评论(0编辑  收藏  举报