老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

Tomcat9如何加載server.xml

小編給大家分享一下Tomcat9如何加載server.xml,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

成都創新互聯堅持“要么做到,要么別承諾”的工作理念,服務領域包括:網站制作、成都網站制作、企業官網、英文網站、手機端網站、網站推廣等服務,滿足客戶于互聯網時代的饒河網站設計、移動媒體設計的需求,幫助企業找到有效的互聯網解決方案。努力成為您成熟可靠的網絡建設合作伙伴!

1.Tomcat啟動

org.apache.catalina.startup.Bootstrap.main(String args[])
 public static void main(String args[]) {
        synchronized (daemonLock) {
            if (daemon == null) {
                Bootstrap bootstrap = new Bootstrap();
                try {
                    bootstrap.init(); //初始化類加載器
                } catch (Throwable t) {
                    handleThrowable(t);
                    t.printStackTrace();
                    return;
                }
                daemon = bootstrap;
            } else {
                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) {
            if (t instanceof InvocationTargetException &&
                    t.getCause() != null) {
                t = t.getCause();
            }
            handleThrowable(t);
            t.printStackTrace();
            System.exit(1);
        }
    }

在main方法中主要為兩部分邏輯:

  • 調用bootstrap.init()進行初始化

  • 根據傳入不同的指令進行相應的處理,本文主要分析start指定,即服務啟動。啟動服務start主要調用了org.apache.catalina.startup.Catalina.load()和start()方法

org.apache.catalina.startup.Bootstrap.init()
 public void init() throws Exception {
        initClassLoaders(); //初始化類加載
        Thread.currentThread().setContextClassLoader(catalinaLoader); //設置當前線程的類加載器為catalinaLoader
        SecurityClassLoad.securityClassLoad(catalinaLoader); //啟用java安全管理的處理
        //通過反射的方式實例化org.apache.catalina.startup.Catalina,并設置父類加載器為sharedLoader
        if (log.isDebugEnabled())
            log.debug("Loading startup class");
        Class startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
        Object startupInstance = startupClass.getConstructor().newInstance();
        if (log.isDebugEnabled())
            log.debug("Setting startup class properties");
        String methodName = "setParentClassLoader";
        Class paramTypes[] = new Class[1];
        paramTypes[0] = Class.forName("java.lang.ClassLoader");
        Object paramValues[] = new Object[1];
        paramValues[0] = sharedLoader;
        Method method =
            startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);
        catalinaDaemon = startupInstance;
    }
  • 類加載器的初始化,創建commonLoader、catalinaLoader、sharedLoader,具體可參考上一篇 《Tomcat9源代碼淺析-類加載體系》

  • 啟用java安全管理的處理

  • 通過反射的方式實例化org.apache.catalina.startup.Catalina,并設置父類加載器為sharedLoader

org.apache.catalina.security.SecurityClassLoad
public final class SecurityClassLoad {
    public static void securityClassLoad(ClassLoader loader) throws Exception {
        securityClassLoad(loader, true);
    }
    static void securityClassLoad(ClassLoader loader, boolean requireSecurityManager) throws Exception {
        if (requireSecurityManager && System.getSecurityManager() == null) {
            return;
        }
        loadCorePackage(loader);
        loadCoyotePackage(loader);
        loadLoaderPackage(loader);
        loadRealmPackage(loader);
        loadServletsPackage(loader);
        loadSessionPackage(loader);
        loadUtilPackage(loader);
        loadJavaxPackage(loader);
        loadConnectorPackage(loader);
        loadTomcatPackage(loader);
    }

當時使用Java SecurityManager時,會提前加載一些必要的java類,以避免觸發權限異常AccessControlException

2.server.xml解析框架

2.1 SAX

Tomcat中使用SAX解析server.xml文件。SAX解析方式會逐行的解析XML文檔,當遇到標簽時會觸發解析處理器,采用事件處理的方式解析XML,它的優點是不需要將完整的XML文檔加載進內存,可以在讀取文檔的同時就進行解析,節省內存,適合解析超大XML,主要方法有:

  • startDocument():文檔解析開始時調用,該方法只會調用一次

  • startElement(String uri, String localName, String qName, Attributes attributes):標簽解析開始時調用

  • endElement(String uri, String localName, String qName):標簽(節點)解析結束后調用

  • endDocument():文檔解析結束后調用,該方法只會調用一次

2.2 規則Rules

Tomcat9如何加載server.xml
Tomcat將server.xml的解析抽象為規則,利用Java的引用傳遞,通過有副作用的void方法,對xml進行解析,規則調用的順序與xml解析的順序是一致的,即start方法是正序,end方法是逆序。
規則中包含以下方法:

  • begin:Degister.startElement 方法調用

  • body、end:Degister.endElement方法中調用,先調用body,再調用end

  • finish:Degister.endDocument方法中調用

Tomcat中常見的規則類型:

  • ObjectCreateRule 創建對應class的對象實例,并放到Designer的堆棧成員屬性中

  • SetPropertiesRule 獲取堆棧中棧頂的元素,并將xml元素的屬性賦值給對象實例

  • SetNextRule 調用父節點的實例對象,將當前對象作為參數,反射調用某個方法

  • ListenerCreateRule 當Listener標簽有optional屬性為true時,創建實例異常時,強制添加OptionalListener實例

  • ConnectorCreateRule 創建Connector實例

  • SetAllPropertiesRule 主體功能與SetPropertiesRule 一致,這個Rule可以排除一些屬性的設置

  • AddPortOffsetRule Set portOffset on all the connectors based on portOffset in the Server

  • CertificateCreateRule 實例化SSLHostConfigCertificate

3.server.xml解析源代碼解析

org.apache.catalina.startup.Catalina.load()
public void load() {
        if (loaded) {
            return;
        }
        loaded = true;
        long t1 = System.nanoTime();
        initDirs();
        // Before digester - it may be needed
        initNaming();
        // 讀取conf/server.xml
        ConfigFileLoader.setSource(new CatalinaBaseConfigurationSource(Bootstrap.getCatalinaBaseFile(), getConfigFile()));
        File file = configFile();
        // 創建xml解析Digester 
        Digester digester = createStartDigester();
        try (ConfigurationSource.Resource resource = ConfigFileLoader.getSource().getServerXml()) {
            InputStream inputStream = resource.getInputStream();
            InputSource inputSource = new InputSource(resource.getURI().toURL().toString());
            inputSource.setByteStream(inputStream);
            digester.push(this);
            digester.parse(inputSource); //解析xml
        } catch (Exception e) {
            log.warn(sm.getString("catalina.configFail", file.getAbsolutePath()), e);
            if (file.exists() && !file.canRead()) {
                log.warn(sm.getString("catalina.incorrectPermissions"));
            }
            return;
        }
        //設置server的屬性
        getServer().setCatalina(this);
        getServer().setCatalinaHome(Bootstrap.getCatalinaHomeFile());
        getServer().setCatalinaBase(Bootstrap.getCatalinaBaseFile());
        // Stream redirection
        initStreams();
        // 初始化server
        try {
            getServer().init();
        } catch (LifecycleException e) {
            if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) {
                throw new java.lang.Error(e);
            } else {
                log.error(sm.getString("catalina.initError"), e);
            }
        }
        long t2 = System.nanoTime();
        if(log.isInfoEnabled()) {
            log.info(sm.getString("catalina.init", Long.valueOf((t2 - t1) / 1000000)));
        }
    }
  • Bootstrap中start指令邏輯,通過反射調用Catalina.load()

  • Catalina.load() 讀取conf/server.xml,創建解析xml的Digester

  • 開始初始化server

org.apache.catalina.startup.Catalina.createStartDigester()
 protected Digester createStartDigester() {
        long t1=System.currentTimeMillis();
        // Initialize the digester
        Digester digester = new Digester();
        digester.setValidating(false);
        digester.setRulesValidation(true);
        Map, List> fakeAttributes = new HashMap<>();
        // Ignore className on all elements
        List objectAttrs = new ArrayList<>();
        objectAttrs.add("className");
        fakeAttributes.put(Object.class, objectAttrs);
        // Ignore attribute added by Eclipse for its internal tracking
        List contextAttrs = new ArrayList<>();
        contextAttrs.add("source");
        fakeAttributes.put(StandardContext.class, contextAttrs);
        // Ignore Connector attribute used internally but set on Server
        List connectorAttrs = new ArrayList<>();
        connectorAttrs.add("portOffset");
        fakeAttributes.put(Connector.class, connectorAttrs);
        digester.setFakeAttributes(fakeAttributes);
        digester.setUseContextClassLoader(true);
        // Configure the actions we will be using
        digester.addObjectCreate("Server",
                                 "org.apache.catalina.core.StandardServer",
                                 "className");
        digester.addSetProperties("Server");
        digester.addSetNext("Server",
                            "setServer",
                            "org.apache.catalina.Server");
        digester.addObjectCreate("Server/GlobalNamingResources",
                                 "org.apache.catalina.deploy.NamingResourcesImpl");
        digester.addSetProperties("Server/GlobalNamingResources");
        digester.addSetNext("Server/GlobalNamingResources",
                            "setGlobalNamingResources",
                            "org.apache.catalina.deploy.NamingResourcesImpl");
        digester.addRule("Server/Listener",
                new ListenerCreateRule(null, "className"));
        digester.addSetProperties("Server/Listener");
        digester.addSetNext("Server/Listener",
                            "addLifecycleListener",
                            "org.apache.catalina.LifecycleListener");
        digester.addObjectCreate("Server/Service",
                                 "org.apache.catalina.core.StandardService",
                                 "className");
        digester.addSetProperties("Server/Service");
        digester.addSetNext("Server/Service",
                            "addService",
                            "org.apache.catalina.Service");
        digester.addObjectCreate("Server/Service/Listener",
                                 null, // MUST be specified in the element
                                 "className");
        digester.addSetProperties("Server/Service/Listener");
        digester.addSetNext("Server/Service/Listener",
                            "addLifecycleListener",
                            "org.apache.catalina.LifecycleListener");
        //Executor
        digester.addObjectCreate("Server/Service/Executor",
                         "org.apache.catalina.core.StandardThreadExecutor",
                         "className");
        digester.addSetProperties("Server/Service/Executor");
        digester.addSetNext("Server/Service/Executor",
                            "addExecutor",
                            "org.apache.catalina.Executor");
        digester.addRule("Server/Service/Connector",
                         new ConnectorCreateRule());
        digester.addRule("Server/Service/Connector", new SetAllPropertiesRule(
                new String[]{"executor", "sslImplementationName", "protocol"}));
        digester.addSetNext("Server/Service/Connector",
                            "addConnector",
                            "org.apache.catalina.connector.Connector");
        digester.addRule("Server/Service/Connector", new AddPortOffsetRule());
        digester.addObjectCreate("Server/Service/Connector/SSLHostConfig",
                                 "org.apache.tomcat.util.net.SSLHostConfig");
        digester.addSetProperties("Server/Service/Connector/SSLHostConfig");
        digester.addSetNext("Server/Service/Connector/SSLHostConfig",
                "addSslHostConfig",
                "org.apache.tomcat.util.net.SSLHostConfig");
        digester.addRule("Server/Service/Connector/SSLHostConfig/Certificate",
                         new CertificateCreateRule());
        digester.addRule("Server/Service/Connector/SSLHostConfig/Certificate",
                         new SetAllPropertiesRule(new String[]{"type"}));
        digester.addSetNext("Server/Service/Connector/SSLHostConfig/Certificate",
                            "addCertificate",
                            "org.apache.tomcat.util.net.SSLHostConfigCertificate");
        digester.addObjectCreate("Server/Service/Connector/SSLHostConfig/OpenSSLConf",
                                 "org.apache.tomcat.util.net.openssl.OpenSSLConf");
        digester.addSetProperties("Server/Service/Connector/SSLHostConfig/OpenSSLConf");
        digester.addSetNext("Server/Service/Connector/SSLHostConfig/OpenSSLConf",
                            "setOpenSslConf",
                            "org.apache.tomcat.util.net.openssl.OpenSSLConf");
        digester.addObjectCreate("Server/Service/Connector/SSLHostConfig/OpenSSLConf/OpenSSLConfCmd",
                                 "org.apache.tomcat.util.net.openssl.OpenSSLConfCmd");
        digester.addSetProperties("Server/Service/Connector/SSLHostConfig/OpenSSLConf/OpenSSLConfCmd");
        digester.addSetNext("Server/Service/Connector/SSLHostConfig/OpenSSLConf/OpenSSLConfCmd",
                            "addCmd",
                            "org.apache.tomcat.util.net.openssl.OpenSSLConfCmd");
        digester.addObjectCreate("Server/Service/Connector/Listener",
                                 null, // MUST be specified in the element
                                 "className");
        digester.addSetProperties("Server/Service/Connector/Listener");
        digester.addSetNext("Server/Service/Connector/Listener",
                            "addLifecycleListener",
                            "org.apache.catalina.LifecycleListener");
        digester.addObjectCreate("Server/Service/Connector/UpgradeProtocol",
                                  null, // MUST be specified in the element
                                  "className");
        digester.addSetProperties("Server/Service/Connector/UpgradeProtocol");
        digester.addSetNext("Server/Service/Connector/UpgradeProtocol",
                            "addUpgradeProtocol",
                            "org.apache.coyote.UpgradeProtocol");
        // Add RuleSets for nested elements
        digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
        digester.addRuleSet(new EngineRuleSet("Server/Service/"));
        digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));
        digester.addRuleSet(new ContextRuleSet("Server/Service/Engine/Host/"));
        addClusterRuleSet(digester, "Server/Service/Engine/Host/Cluster/");
        digester.addRuleSet(new NamingRuleSet("Server/Service/Engine/Host/Context/"));
        // When the 'engine' is found, set the parentClassLoader.
        digester.addRule("Server/Service/Engine",
                         new SetParentClassLoaderRule(parentClassLoader));
        addClusterRuleSet(digester, "Server/Service/Engine/Cluster/");
        long t2=System.currentTimeMillis();
        if (log.isDebugEnabled()) {
            log.debug("Digester for server.xml created " + ( t2-t1 ));
        }
        return digester;
    }

此方法創建解析server.xml的Digester,根據server.xml的元素標簽,為每個標簽設置相應的規則組,在解析標簽時進行調用。
由此也可以得到結論,server.xml的結構就是Tomcat容器內部的結構,通過對server.xml的解析規則的執行,實例化出Tomcat容器結構。

以下為Tomcat9默認的server.xml



  
  
  
  
  
  
    
  
  
    
    
    
      
        
        
      
      
        
      
    
  

其結構見下圖:
Tomcat9如何加載server.xml

  • Server代表服務器,一個Tomcat只有一個Server

  • Service 代表服務: 一個Server可以對外提供多個服務

  • Connector連接器: service服務的核心組成之一,主要是鏈接客戶端請求

  • Container容器:service服務的核心組成之一,主要是執行業務邏輯,這里按層級為Engine、Host、Context

  • Wrapper:對應Servlet的定義
    Tomcat9如何加載server.xml

以上是“Tomcat9如何加載server.xml”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注創新互聯行業資訊頻道!


當前標題:Tomcat9如何加載server.xml
轉載來于:http://www.xueling.net.cn/article/poseog.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 超碰97人人做人人爱亚洲 | 少妇高潮喷水正在播放 | 91神马影院 | 人妻丝袜无码专区视频网站 | 日韩在线观看视频免费 | 欧美亚洲一区二区在线观看 | 亚洲成人精品久久久 | 琪琪午夜成人理论福利片美容院 | 久艹在线免费观看 | 这里只有久久精品 | 亚洲AV无码专区亚洲AV紧身裤 | 精品大片一区二区 | 粉嫩一区二区三区国产精品 | 色婷婷伊人 | 狂野欧美性猛交免费视频 | 国产高清无码在线一区二区 | 蜜桃视频一区二区三区在线观看 | 91porny国产 | 蜜桃视频插满18在线观看 | 91l九色lporny | 伊人国产在线播放 | 国产精品久久久影视青草 | 网色国产 | 日韩国产欧美一区二区 | 国产欧美性 | 欧美xxx在线观看 | 亚洲高清国产AV拍精品青青草原 | 狠狠操在线视频 | 97超碰人人爱香蕉精品 | 成人97精品毛片免费看 | 国产播放隔着超薄丝袜进入 | 伊人11 | 久久亚洲网 | 日本一区二区三区免费高清 | 精品国产一区二区三区四 | 久操网在线 | 国产精品一区二区av片 | 老外黑人欧美一级毛片 | 3d动漫精品久久一区二区 | 国产精品丝袜久久久久久消防器材 | 亚洲AV成人一区二区三区网站 |