欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

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)前線(xiàn)程的類(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ù)脑?,并將xml元素的屬性賦值給對(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<Class<?>, List<String>> fakeAttributes = new HashMap<>();
        // Ignore className on all elements
        List<String> objectAttrs = new ArrayList<>();
        objectAttrs.add("className");
        fakeAttributes.put(Object.class, objectAttrs);
        // Ignore attribute added by Eclipse for its internal tracking
        List<String> contextAttrs = new ArrayList<>();
        contextAttrs.add("source");
        fakeAttributes.put(StandardContext.class, contextAttrs);
        // Ignore Connector attribute used internally but set on Server
        List<String> 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

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

其結(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è)資訊頻道!

標(biāo)題名稱(chēng):Tomcat9如何加載server.xml-創(chuàng)新互聯(lián)
文章路徑:http://aaarwkj.com/article22/gjjjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開(kāi)發(fā)、電子商務(wù)自適應(yīng)網(wǎng)站、用戶(hù)體驗(yàn)靜態(tài)網(wǎng)站、品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)
无遮挡动漫网站免费观看| 欧美日韩在线观看黄色| 欧美一区二区日韩一区二区| 久久亚洲中文字幕丝袜长腿 | 中文字幕日韩人妻av| 免费国产污在线观看网站| 不卡在线视频中文字幕| 91色九色吧在线观看| 丝袜美腿美女日韩在线| 调教亚洲另类唯美第二页| 91伊人日本在线视频| 成人又黄又爽大片在线观看| 中国成熟女人毛茸茸视频| 亚洲美女国产精选999| 日韩不卡的一区免费视频| 成人av男人天堂东京热| 亚洲天堂日韩欧美在线| 亚洲精品中文字幕乱码| 精品视频一区二区三区在线观看 | 日本午夜激情一区二区| 国产黄色一区二区三区,| 人妻有码系列中文字幕专区| 涩久久悠悠一区二区三区| 禁止未满十八在线观看| 亚洲精品福利一二三区| 国产白丝扒开做爽爽爽网站| 久久久久久成人亚洲| 亚洲一区成人免费电影| 日韩中文字幕亚洲精品一| 午夜美女精品福利视频| 亚洲av乱码毛片在线播放| 国产精品国产三级国av中文| 国产亚洲日本一区二区三区| 麻豆蜜桃精品视频在线观看| 后入蜜桃臀美女在线观看| 青青草视频在线好好热| 亚洲综合香蕉在线视频| 日韩久久这里只有精品视频| 久久麻豆精亚洲av品国产一区| 国产中文字幕精品在线| 一区二区三区人妻系列|