zoukankan      html  css  js  c++  java
  • Tomcat8.5.50

    Tomcat 核心思想

    servlet? web容器/servlet容器 tomcat是servlet的容器,每个请求是servlet ,每个servlet里面包含了request,response 

    tomcat 包含了很多servlet  tomcat

    使用Http11NioProtocol

     

    Http11NioProtocol

    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

     

     <Context path="/" docBase="/root/tomcat/apache-tomcat-8.0.30/fantasy" /> 以web项目为单位加载servlet

     Context: A Context represents a web application. (代表一个web项目)

    看server.xml,每一个标签都有对应的java 类,其他源码也可以参照如此学习

    Context:

    public interface Context extends Container, ContextBind {
    StandardContext

    public boolean loadOnStartup(Container children[]) { // Collect "load on startup" servlets that need to be initialized 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) continue; Integer key = Integer.valueOf(loadOnStartup); ArrayList<Wrapper> list = map.get(key); if (list == null) { list = new ArrayList<>(); map.put(key, list); }
    //将每个servlet添加到容器中 list.add(wrapper); }
    // Load the collected "load on startup" servlets for (ArrayList<Wrapper> list : map.values()) { for (Wrapper wrapper : list) { try { wrapper.load(); } catch (ServletException e) { getLogger().error(sm.getString("standardContext.loadOnStartup.loadException", getName(), wrapper.getName()), StandardWrapper.getRootCause(e)); // NOTE: load errors (including a servlet that throws // UnavailableException from the init() method) are NOT // fatal to application startup // unless failCtxIfServletStartFails="true" is specified if(getComputedFailCtxIfServletStartFails()) { return false; } } } } return true; }

    Wrapper 是否是Servlet?

    public class ContextConfig implements LifecycleListener {
    protected void webConfig() {
    WebXmlParser webXmlParser = new WebXmlParser(context.getXmlNamespaceAware(),
    context.getXmlValidation(), context.getXmlBlockExternal());

    Set<WebXml> defaults = new HashSet<>();
    defaults.add(getDefaultWebXmlFragment(webXmlParser));

    WebXml webXml = createWebXml();

    // Parse context level web.xml
    InputSource contextWebXml = getContextWebXmlSource();
    if (!webXmlParser.parseWebXml(contextWebXml, webXml, false)) {
    ok = false;
    }
     }   

    //1 创建webXml

    WebXml webXml = createWebXml();
    public class WebXml {
    //加载web.xml
    private static final StringManager sm =
    StringManager.getManager(Constants.PACKAGE_NAME);
    }
    public class Constants {

    public static final String PACKAGE_NAME =
    Constants.class.getPackage().getName();

    public static final String WEB_XML_LOCATION = "/WEB-INF/web.xml";

    }
    getContextWebXmlSource
    stream = servletContext.getResourceAsStream
    (Constants.ApplicationWebXml);
    try {
    url = servletContext.getResource(
    Constants.ApplicationWebXml);
    } catch (MalformedURLException e) {
    log.error(sm.getString("contextConfig.applicationUrl"));
    }
    Constants {
    
        public static final String Package = "org.apache.catalina.startup";
    
        public static final String ApplicationContextXml = "META-INF/context.xml";
    //找到 web-inf/web.xml
    public static final String ApplicationWebXml = "/WEB-INF/web.xml"; public static final String DefaultContextXml = "conf/context.xml"; public static final String DefaultWebXml = "conf/web.xml"; public static final String HostContextXml = "context.xml.default"; public static final String HostWebXml = "web.xml.default"; public static final String WarTracker = "/META-INF/war-tracker";
      // Step 9. Apply merged web.xml to Context
                if (ok) {
                    configureContext(webXml);
                }
    // 加载web.xml,将servlet 进行包装 ,包装为wrapper
    for (ServletDef servlet : webxml.getServlets().values()) {
                Wrapper wrapper = context.createWrapper();
                // Description is ignored
                // Display name is ignored
                // Icons are ignored
    
                // jsp-file gets passed to the JSP Servlet as an init-param
    
                if (servlet.getLoadOnStartup() != null) {
                    wrapper.setLoadOnStartup(servlet.getLoadOnStartup().intValue());
                }
                if (servlet.getEnabled() != null) {
                    wrapper.setEnabled(servlet.getEnabled().booleanValue());
                }
                wrapper.setName(servlet.getServletName());
                Map<String,String> params = servlet.getParameterMap();
                for (Entry<String, String> entry : params.entrySet()) {
                    wrapper.addInitParameter(entry.getKey(), entry.getValue());
                }
                wrapper.setRunAs(servlet.getRunAs());
                Set<SecurityRoleRef> roleRefs = servlet.getSecurityRoleRefs();
                for (SecurityRoleRef roleRef : roleRefs) {
                    wrapper.addSecurityReference(
                            roleRef.getName(), roleRef.getLink());
                }
                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) {
                    wrapper.setAsyncSupported(
                            servlet.getAsyncSupported().booleanValue());
                }
                wrapper.setOverridable(servlet.isOverridable());
                context.addChild(wrapper);
            }

    监听端口

     <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    Connector查找监听端口

    第一步 入口类:Bootstrap
    //Bootstrap 当执行命令的时候执行的改方法
    public static void main(String args[]) {
    
            synchronized (daemonLock) {
                if (daemon == null) {
                    // Don't set daemon until init() has completed
                    Bootstrap bootstrap = new Bootstrap();
                    try {
                        bootstrap.init();
                    } catch (Throwable t) {
                        handleThrowable(t);
                        t.printStackTrace();
                        return;
                    }
                    daemon = bootstrap;
                } else {
                    // When running as a service the call to stop will be on a new
                    // thread so make sure the correct class loader is used to
                    // prevent a range of class not found exceptions.
                    Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
                }
            }
    
            try {
                String command = "start";
                if (args.length > 0) {
                    command = args[args.length - 1];
                }
    
                if (command.equals("startd")) {
                    args[args.length - 1] = "start";
                    daemon.load(args);
                    daemon.start();
                } else if (command.equals("stopd")) {
                    args[args.length - 1] = "stop";
                    daemon.stop();
                } else if (command.equals("start")) {
                    daemon.setAwait(true);
                    daemon.load(args);
                    daemon.start();
                    if (null == daemon.getServer()) {
                        System.exit(1);
                    }
                } else if (command.equals("stop")) {
                    daemon.stopServer(args);
                } else if (command.equals("configtest")) {
                    daemon.load(args);
                    if (null == daemon.getServer()) {
                        System.exit(1);
                    }
                    System.exit(0);
                } else {
                    log.warn("Bootstrap: command "" + command + "" does not exist.");
                }
            } catch (Throwable t) {
                // Unwrap the Exception for clearer error reporting
                if (t instanceof InvocationTargetException &&
                        t.getCause() != null) {
                    t = t.getCause();
                }
                handleThrowable(t);
                t.printStackTrace();
                System.exit(1);
            }
        }

    2 启动命令;

       if (command.equals("startd")) {
                    args[args.length - 1] = "start";
    // 加载 tomcat 下面的conf/server.xml daemon.load(args);
    // 启动 基于对这些对象合作完成相应的功能 daemon.start();
    }
     private void load(String[] arguments) throws Exception {
    
            // Call the load() method
            String methodName = "load";
            Object param[];
            Class<?> paramTypes[];
            if (arguments==null || arguments.length==0) {
                paramTypes = null;
                param = null;
            } else {
                paramTypes = new Class[1];
                paramTypes[0] = arguments.getClass();
                param = new Object[1];
                param[0] = arguments;
            }
            Method method =
                catalinaDaemon.getClass().getMethod(methodName, paramTypes);
            if (log.isDebugEnabled()) {
                log.debug("Calling startup class " + method);
            }
            method.invoke(catalinaDaemon, param);
        }
    public class Catalina {
    // Start a new server instance. 创建一个server对象
    public void load() {} }
    file = configFile();
    //加载tomcat的server.xml文件
    protected String configFile = "conf/server.xml";
    
    
    // Start the new server 创建server并初始化 
    try {
    getServer().init();
    }
    //生命周期Lifecycle
    //默认实现类:LifecycleBase
    //initInternal()
    //StandardServer->initInternal->globalNamingResources
    // Initialize our defined Services 
    //初始化services是
    for (int i = 0; i < services.length; i++) {
    //1 初始化service LifecycleBase->init->initInternal->StandardService->initInternal

         services[i].init();

    //2 初始化Connector LifecycleBase->init->initInternal->Connector->initInternal

    synchronized (connectorsLock) {
    for (Connector connector : connectors) {
    connector.init();
    }
    //3 初始化protocol protocolHandler.init()->AbstractProtocol.init()->endpoint.init()->AbstractEndpoint
    if (bindOnInit) {
    bind();
    //选择不同的IO tomcat8 默认NIO tomcat7默认 BIO 在server.xml中的protocol="HTTP/1.1" 可以查看默认IO方式
    在Connector 中构造函数public Connector(String protocol)->setProtocol 查看具体实现IO方式

    bindState = BindState.BOUND_ON_INIT;
    }

    }

      

     Host发布方式

    HostConfig -deployApps  

        protected void deployApps() {
    
            File appBase = host.getAppBaseFile();
            File configBase = host.getConfigBaseFile();
            String[] filteredAppPaths = filterAppPaths(appBase.list());
            // Deploy XML descriptors from configBase 基于xml发布
            deployDescriptors(configBase, configBase.list());
            // Deploy WARs 基于war发布
            deployWARs(appBase, filteredAppPaths);
            // Deploy expanded folders 文件夹方式发布
            deployDirectories(appBase, filteredAppPaths);
    
        }

     Digester解析 xml文件 

  • 相关阅读:
    Javascript FP-ramdajs
    微信小程序开发
    SPA for HTML5
    One Liners to Impress Your Friends
    Sass (Syntactically Awesome StyleSheets)
    iOS App Icon Template 5.0
    React Native Life Cycle and Communication
    Meteor framework
    RESTful Mongodb
    Server-sent Events
  • 原文地址:https://www.cnblogs.com/fanBlog/p/12195878.html
Copyright © 2011-2022 走看看