• 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文件 

  • 相关阅读:
    Xcopy参数介绍
    C# 子窗体中调用父窗体中的方法(或多窗体之间方法调用)
    WinForm窗体之间交互的一些方法(转)
    C#.Net组件开发 使用Attach to Process实时调试设计器代码(转)
    win7以管理员身份运行程序
    如何关闭Windows7的UAC
    用“回车”键代替“Tab”键
    笑话20110928
    项目管理师
    软考计算机技术与软件专业技术资格(水平)考试
  • 原文地址:https://www.cnblogs.com/fanBlog/p/12195878.html
Copyright © 2020-2023  润新知