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

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)
日本中文字幕免费专区| 女同久久精品国产精品天堂99| 黄色大片黄色大片黄色大片| 精精国产xxxx视频在线不卡| 亚洲综合久久五月天| 久章草在线免费视频播放| 日韩精品女性三级视频| 亚洲日本欧洲二区精品| 18以下的人禁止看的视频| 国产黄色片网站在线看| 国产成人精品一区二区国产乱码| 亚洲成a人片777777久久| 久久激情日本人妻av免费| 麻豆国产av巨做国产剧情| 久久国产精品午夜视频| 日本精品在线亚洲国产欧美| 中文字幕在线不卡精品视频| 欧美黄色一区二区三区精品 | 日本av东京热在线播放| 亚洲熟女熟妇另类中文| 亚洲色图综合在线观看| 欧美日韩亚洲人人夜夜澡| 日本一区二区国产在线| 韩日男人女人性生活视频| 黄色大全欧美在线观看| 黄片欧美精品在线观看| 日韩欧美午夜福利在线视频| 亚洲精品国产av一区二区三区| 国产三级在线观看视频| 国产精品亚洲二区三区| 亚洲精品一区二区成人影院| 男男啪啪猛进猛出无遮挡| 下载一个日韩暴力黄色录像| 亚洲精品a在线观看av| 午夜亚洲欧美日韩在线| 亚洲国产成人综合一区二区三区| 国产乱一伦一性一情一色| 三级黄色片免费久久久| 一区二区三区四区在线视频观看| 97人妻人人澡人人爽| 色伊人久久综合中文字幕|