真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Tomcat9如何加載server.xml-創(chuàng)新互聯(lián)

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

站在用戶(hù)的角度思考問(wèn)題,與客戶(hù)深入溝通,找到石首網(wǎng)站設(shè)計(jì)與石首網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶(hù)體驗(yàn)好的作品,建站類(lèi)型包括:網(wǎng)站制作、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國(guó)際域名空間、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋石首地區(qū)。

1.Tomcat啟動(dòng)

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(); //初始化類(lèi)加載器
                } catch (Throwable t) {
                    handleThrowable(t);
                    t.printStackTrace();
                    return;
                }
                daemon = bootstrap;
            } else {
                Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
            }
        }
        //根據(jù)傳入的不同指令,進(jìn)行相應(yīng)處理
        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方法中主要為兩部分邏輯:

  • 調(diào)用bootstrap.init()進(jìn)行初始化

  • 根據(jù)傳入不同的指令進(jìn)行相應(yīng)的處理,本文主要分析start指定,即服務(wù)啟動(dòng)。啟動(dòng)服務(wù)start主要調(diào)用了org.apache.catalina.startup.Catalina.load()和start()方法

org.apache.catalina.startup.Bootstrap.init()
 public void init() throws Exception {
        initClassLoaders(); //初始化類(lèi)加載
        Thread.currentThread().setContextClassLoader(catalinaLoader); //設(shè)置當(dāng)前線程的類(lèi)加載器為catalinaLoader
        SecurityClassLoad.securityClassLoad(catalinaLoader); //啟用java安全管理的處理
        //通過(guò)反射的方式實(shí)例化org.apache.catalina.startup.Catalina,并設(shè)置父類(lèi)加載器為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;
    }
  • 類(lèi)加載器的初始化,創(chuàng)建commonLoader、catalinaLoader、sharedLoader,具體可參考上一篇 《Tomcat9源代碼淺析-類(lèi)加載體系》

  • 啟用java安全管理的處理

  • 通過(guò)反射的方式實(shí)例化org.apache.catalina.startup.Catalina,并設(shè)置父類(lèi)加載器為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);
    }

當(dāng)時(shí)使用Java SecurityManager時(shí),會(huì)提前加載一些必要的java類(lèi),以避免觸發(fā)權(quán)限異常AccessControlException

2.server.xml解析框架

2.1 SAX

Tomcat中使用SAX解析server.xml文件。SAX解析方式會(huì)逐行的解析XML文檔,當(dāng)遇到標(biāo)簽時(shí)會(huì)觸發(fā)解析處理器,采用事件處理的方式解析XML,它的優(yōu)點(diǎn)是不需要將完整的XML文檔加載進(jìn)內(nèi)存,可以在讀取文檔的同時(shí)就進(jìn)行解析,節(jié)省內(nèi)存,適合解析超大XML,主要方法有:

  • startDocument():文檔解析開(kāi)始時(shí)調(diào)用,該方法只會(huì)調(diào)用一次

  • startElement(String uri, String localName, String qName, Attributes attributes):標(biāo)簽解析開(kāi)始時(shí)調(diào)用

  • endElement(String uri, String localName, String qName):標(biāo)簽(節(jié)點(diǎn))解析結(jié)束后調(diào)用

  • endDocument():文檔解析結(jié)束后調(diào)用,該方法只會(huì)調(diào)用一次

2.2 規(guī)則Rules

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

  • begin:Degister.startElement 方法調(diào)用

  • body、end:Degister.endElement方法中調(diào)用,先調(diào)用body,再調(diào)用end

  • finish:Degister.endDocument方法中調(diào)用

Tomcat中常見(jiàn)的規(guī)則類(lèi)型:

  • ObjectCreateRule 創(chuàng)建對(duì)應(yīng)class的對(duì)象實(shí)例,并放到Designer的堆棧成員屬性中

  • SetPropertiesRule 獲取堆棧中棧頂?shù)脑兀ml元素的屬性賦值給對(duì)象實(shí)例

  • SetNextRule 調(diào)用父節(jié)點(diǎn)的實(shí)例對(duì)象,將當(dāng)前對(duì)象作為參數(shù),反射調(diào)用某個(gè)方法

  • ListenerCreateRule 當(dāng)Listener標(biāo)簽有optional屬性為true時(shí),創(chuàng)建實(shí)例異常時(shí),強(qiáng)制添加OptionalListener實(shí)例

  • ConnectorCreateRule 創(chuàng)建Connector實(shí)例

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

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

  • CertificateCreateRule 實(shí)例化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();
        // 創(chuàng)建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;
        }
        //設(shè)置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指令邏輯,通過(guò)反射調(diào)用Catalina.load()

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

  • 開(kāi)始初始化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;
    }

此方法創(chuàng)建解析server.xml的Digester,根據(jù)server.xml的元素標(biāo)簽,為每個(gè)標(biāo)簽設(shè)置相應(yīng)的規(guī)則組,在解析標(biāo)簽時(shí)進(jìn)行調(diào)用。
由此也可以得到結(jié)論,server.xml的結(jié)構(gòu)就是Tomcat容器內(nèi)部的結(jié)構(gòu),通過(guò)對(duì)server.xml的解析規(guī)則的執(zhí)行,實(shí)例化出Tomcat容器結(jié)構(gòu)。

以下為T(mén)omcat9默認(rèn)的server.xml



  
  
  
  
  
  
    
  
  
    
    
    
      
        
        
      
      
        
      
    
  

其結(jié)構(gòu)見(jiàn)下圖:
Tomcat9如何加載server.xml

  • Server代表服務(wù)器,一個(gè)Tomcat只有一個(gè)Server

  • Service 代表服務(wù): 一個(gè)Server可以對(duì)外提供多個(gè)服務(wù)

  • Connector連接器: service服務(wù)的核心組成之一,主要是鏈接客戶(hù)端請(qǐng)求

  • Container容器:service服務(wù)的核心組成之一,主要是執(zhí)行業(yè)務(wù)邏輯,這里按層級(jí)為Engine、Host、Context

  • Wrapper:對(duì)應(yīng)Servlet的定義
    Tomcat9如何加載server.xml

以上是“Tomcat9如何加載server.xml”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道!


當(dāng)前題目:Tomcat9如何加載server.xml-創(chuàng)新互聯(lián)
文章出自:http://weahome.cn/article/gjjjc.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部