国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Tomcat研究之ClassLoader
在研究Tomcat之前,一般是借用現(xiàn)有的UML工具分析Tomcat整體結(jié)構(gòu),但要分析Tomcat的流程就必須從分析Tomcat的StartUp入手。Tomcat的啟動(dòng)是從解析bat文件開始,bat文件最終調(diào)用org.apache.catalina.startup.Bootstrap開始類的加載。
一.Tomcat的ClassLoader:
    TOMCAT自己的類載入器(ClassLoader)
       +---------------------------+
       |         Bootstrap         |
       |             |             |
       |          System           |
       |             |             |
       |          Common           |
       |         /      \          |
       |     Catalina Shared      |
       +---------------------------+
     其中:
     - Bootstrap - 載入JVM自帶的類和$JAVA_HOME/jre/lib/ext/*.jar
     - System   
1.載入$CATALINA_HOME/bin/bootstrap.jar 初始化Tomcat,執(zhí)行Main方法
2. $JAVA_HOME/lib/tools.jar Sun的工具類,包括編譯Jsp為Servlet的工具類
   - Common     這個(gè)目錄下的類雖然對(duì)TOMCAT和所有的WEB APP都可見.但是Web App的類不應(yīng)該
                    放在這個(gè)目錄下,所有未打包的Class都在$CATALINA_HOME/common/classes下,所
                    有打包的jar都在
                    $CATALINA_HOME/commons/endorsed和$CATALINA_HOME/common/lib下,默認(rèn)情況會(huì)
                    包含以下幾個(gè)包:
                    1. jndi.jar JNDI API接口,這個(gè)包僅在Java1.2時(shí)候裝入,1.3以后的版本JDK已
                    自動(dòng)裝入.
                    2. naming-common.jar JNDI接口實(shí)現(xiàn)類,Tomcat用這些類在內(nèi)存中使用Context.
                    3. naming-resources.jar JNDI實(shí)現(xiàn),Tomcat用它們定位Web App的靜態(tài)資源.
                    4. servlet.jar Servlet,Jsp API
                    5. xerces.jar XML解析器,特定的Web App可以在自己的/WEB-INF/lib 中覆蓋.
 
   - Catalina 裝入Tomcat實(shí)現(xiàn)所有接口的類,這些類對(duì)Web App是完全不可見的,所有未打包的類在
                    $CATALINA_HOME/server/classes所有jar包在$CATALINA_HOME/server/lib下.一
                    般情況該ClassLoader將Load下面幾個(gè)包:
                    1. catalina.jar Servlet容器的Tomcat實(shí)現(xiàn)包
                    2. jakarta-regexp-X.Y.jar 正則表達(dá)式,請(qǐng)求過濾時(shí)使用
                    3. servlets-xxxxx.jar Servlet支持包
                    4. tomcat-coyote.jar Tomcat的Coyote連接實(shí)現(xiàn)包
                    5. tomcat-jk.jar Web Server綁定包,允許Tomcat綁定Apache等作為Web Server
                    6. tomcat-jk2.jar 功能同上
                    7. tomcat-util.jar Tomcat工具類,可能被一些Connector用到
                    8. tomcat-warp.jar 用于Apache Server包
     - Shared   載入所有WEB APP都可見的類,對(duì)TOMCAT不可見. 所有未打包的類在
                    $CATALINA_HOME/shared/classes所有jar包在$CATALINA_HOME /lib下.
                    默認(rèn)情況包含下面幾個(gè)包:
                    1. jasper-compiler.jar Jsp編譯器,編譯Jsp為Servlet
                    2. jasper-runtime.jar Jsp(已編譯成Servlet)運(yùn)行支持包
                    3. naming-factory.jar 支持Web App使用JNDI的封裝包
     -WebAppX   Web App ClassLoader,當(dāng)Web App被部署是該ClassLoader被創(chuàng)建.所有class都在
                    WEB-INF/classes下,所有jar在WEB-INF/lib下.
  
 特別注意WEB APP自己的ClassLoader的實(shí)現(xiàn)與眾不同:
 它先試圖從WEB APP自己的目錄里載入,如果失敗則請(qǐng)求父ClassLoader的代理
 這樣可以讓不同的WEB APP之間的類載入互不干擾.另,Tomcat Server使用的是Catalina   
 ClassLoader,一般的Web App使用的是WebApp ClassLoader.
二. org.apache.catalina.startup.Bootstrap
          該類是Tomcat的執(zhí)行入口點(diǎn),我們著重分析下面兩個(gè)方法:
          1. initClassLoaders,創(chuàng)建ClassLoader層次.
           private void initClassLoaders() {
                try {
                          ClassLoaderFactory.setDebug(debug);
                          //創(chuàng)建common ClassLoader,沒有父ClassLoader
                          commonLoader = createClassLoader("common", null);
 
                          //創(chuàng)建catalina ClassLoader,父ClassLoader為common
                          catalinaLoader = createClassLoader("server", commonLoader);
 
                          //創(chuàng)建shared ClassLoader, 父ClassLoader為common
                          sharedLoader = createClassLoader("shared", commonLoader);
                     } catch (Throwable t) {
                          log("Class loader creation threw exception", t);
                          System.exit(1);
                     }
             }
          2. createClassLoader,負(fù)責(zé)具體的創(chuàng)建工作
             在$CATALINA_HOME/conf/catalina.properties中定義了common, server, shared
             ClassLoader載入類的路徑及一些包的安全權(quán)限.
         
             //common載入類的路徑
             common.loader=${catalina.home}/common/classes,
             ${catalina.home}/common/endorsed/*.jar,${catalina.home}/common/lib/*.jar
                //server載入類的路徑
                server.loader=${catalina.home}/server/classes,
                               ${catalina.home}/server/lib/*.jar
 
                //shared載入類的路徑
                shared.loader=${catalina.base}/shared/classes,
                               ${catalina.base}/shared/lib/*.jar
         
        /**
          *param name:Load Name
          *param parent:父Loader
          *classLoader的資源分三種:
          *1.未打包的classes,一般是一個(gè)目錄
          *2.打包的jar目錄
          *3.網(wǎng)絡(luò)資源,一般是網(wǎng)上的一個(gè)jar包 (Applet經(jīng)常用到這樣的loader)
          */
        private ClassLoader createClassLoader(String name, ClassLoader parent)
                    throws Exception {
 
          //從catalina.properties中取得改Loader的配置信息
         String value = CatalinaProperties.getProperty(name + ".loader");
         if ((value == null) || (value.equals("")))
                    return parent;
         
          //classes目錄
     ArrayList unpackedList = new ArrayList();
          //jar目錄
      ArrayList packedList = new ArrayList();
          //網(wǎng)絡(luò)路徑指定的包
      ArrayList urlList = new ArrayList();
 
           StringTokenizer tokenizer = new StringTokenizer(value, ",");
            
             //當(dāng)前Loader該裝載的類
             while (tokenizer.hasMoreElements()) {
                    String repository = tokenizer.nextToken();
                    // Check for a JAR URL repository
            try {
                //如果是網(wǎng)絡(luò)路徑追加url
                urlList.add(new URL(repository));
                continue;
            } catch (MalformedURLException e) {
                // Ignore
            }
 
            // 本地路徑
            boolean packed = false;
 
           //${catalina.home}
            if (repository.startsWith(CATALINA_HOME_TOKEN)) {
                repository = getCatalinaHome()
                    + repository.substring(CATALINA_HOME_TOKEN.length());
           //${catalina.base}
           } else if (repository.startsWith(CATALINA_BASE_TOKEN)) {
                repository = getCatalinaBase()
                    + repository.substring(CATALINA_BASE_TOKEN.length());
                    }
                    /**經(jīng)過上述操作,把catalina.properties里的路徑替換成絕對(duì)路徑*/
           
           //如果是jar文件路徑
           if (repository.endsWith("*.jar")) {
                packed = true;
                repository = repository.substring
                    (0, repository.length() - "*.jar".length());
            }
            if (packed) {
                packedList.add(new File(repository));
            } else {
                unpackedList.add(new File(repository));
            }
        }
 
        File[] unpacked = (File[]) unpackedList.toArray(new File[0]);
        File[] packed = (File[]) packedList.toArray(new File[0]);
        URL[] urls = (URL[]) urlList.toArray(new URL[0]);
 
        //調(diào)用Factory的方法創(chuàng)建ClassLoader
        return ClassLoaderFactory.createClassLoader
            (unpacked, packed, urls, parent);
    }


 

三. ClassLoaderFactory
          ClassLoaderFactory是用于創(chuàng)建ClassLoader的工廠類,這個(gè)類比較簡(jiǎn)單.
         
//參數(shù)含義不再說明,參看上面的分析
public static ClassLoader createClassLoader(File unpacked[],
                                                File packed[],
                                                URL urls[],
                                                ClassLoader parent)
        throws Exception {
 
        if (debug >= 1)
            log("Creating new class loader");
 
        // Construct the "class path" for this class loader
        ArrayList list = new ArrayList();
 
        // 通過class目錄構(gòu)造file協(xié)議的url,并追加的list
        if (unpacked != null) {
            for (int i = 0; i < unpacked.length; i++) {
                File file = unpacked[i];
                if (!file.exists() || !file.canRead())
                    continue;
                if (debug >= 1)
                    log(" Including directory or JAR "
                        + file.getAbsolutePath());
                URL url = new URL("file", null,
                                  file.getCanonicalPath() + File.separator);
                list.add(url.toString());
            }
        }
 
        //取出所有jar目錄里的jar文件,逐一構(gòu)造url,并追加的list
        if (packed != null) {
            for (int i = 0; i < packed.length; i++) {
                File directory = packed[i];
                if (!directory.isDirectory() || !directory.exists() ||
                    !directory.canRead())
                    continue;
                String filenames[] = directory.list();
                for (int j = 0; j < filenames.length; j++) {
                    String filename = filenames[j].toLowerCase();
                    if (!filename.endsWith(".jar"))
                        continue;
                    File file = new File(directory, filenames[j]);
                    if (debug >= 1)
                        log(" Including jar file " + file.getAbsolutePath());
                    URL url = new URL("file", null,
                                      file.getCanonicalPath());
                    list.add(url.toString());
                }
            }
        }
 
        //追加網(wǎng)絡(luò)路徑的資源
        if (urls != null) {
            for (int i = 0; i < urls.length; i++) {
                list.add(urls[i].toString());
            }
        }
 
        //調(diào)用StandardClassLoader創(chuàng)建實(shí)際的Loader
        String array[] = (String[]) list.toArray(new String[list.size()]);
        StandardClassLoader classLoader = null;
        if (parent == null)
            classLoader = new StandardClassLoader(array);
        else
            classLoader = new StandardClassLoader(array, parent);
        classLoader.setDelegate(true);
        return (classLoader);
 
   }
四. StandardClassLoader
          StandardClassLoader繼承了URLClassLoader, URLClassLoader類具有從硬盤目錄裝載類,或從本地或遠(yuǎn)程裝載jar文件的能力.這個(gè)類也實(shí)現(xiàn)了Reloader接口,提供了自動(dòng)重新裝載類的功能.我們主要看這個(gè)類以下及個(gè)方法:
1.      構(gòu)造函數(shù)StandardClassLoader
   /**
     * @param repositories url數(shù)組,見上分析
     * @param parent 父loader
     */
    public StandardClassLoader(String repositories[], ClassLoader parent) {
       //調(diào)用父類的構(gòu)造函數(shù)
       //父類的構(gòu)造函數(shù)將用轉(zhuǎn)換后的repositories生成URLClassPath的實(shí)例
       //ucp是類成員變量ucp=new URLClassPath(urls);
      // URLClassPath是sun的擴(kuò)展包,無法繼續(xù)跟蹤
        super(convert(repositories), parent);
        this.parent = parent;
        this.system = getSystemClassLoader();
        securityManager = System.getSecurityManager();
     if (repositories != null) {
            for (int i = 0; i < repositories.length; i++)
                //處理url
                addRepositoryInternal(repositories[i]);
        }
    }
2.      addRepositoryInternal
   /**
     * @param repository 要處理的url
     */
    protected void addRepositoryInternal(String repository) {
 
        URLStreamHandler streamHandler = null;
        String protocol = parseProtocol(repository);
        if (factory != null)
            streamHandler = factory.createURLStreamHandler(protocol);
 
        // 當(dāng)前url是指向本地或網(wǎng)路的jar文件,驗(yàn)證jar的正確性
        //下面的代碼看似無用其實(shí)是在驗(yàn)證jar文件的正確性,如果jar文件錯(cuò)誤拋異常中止執(zhí)行.
        if (!repository.endsWith(File.separator) && !repository.endsWith("/")) {
            JarFile jarFile = null;
            try {
                Manifest manifest = null;
 
                //jar協(xié)議
                if (repository.startsWith("jar:")) {
                    URL url = new URL(null, repository, streamHandler);
                    JarURLConnection conn =
                        (JarURLConnection) url.openConnection();
                    conn.setAllowUserInteraction(false);
                    conn.setDoInput(true);
                    conn.setDoOutput(false);
                    conn.connect();
                    jarFile = conn.getJarFile();
               
                //file協(xié)議
                } else if (repository.startsWith("file://")) {
                    jarFile = new JarFile(repository.substring(7));
                //file
                } else if (repository.startsWith("file:")) {
                    jarFile = new JarFile(repository.substring(5));
 
                //本地路徑的jar文件
                } else if (repository.endsWith(".jar")) {
                    URL url = new URL(null, repository, streamHandler);
                    URLConnection conn = url.openConnection();
                    JarInputStream jis =
                        new JarInputStream(conn.getInputStream());
                    manifest = jis.getManifest();
 
                //其他情況均為錯(cuò)誤
                } else {
                    throw new IllegalArgumentException
                        ("addRepositoryInternal: Invalid URL '" +
                         repository + "'");
     &
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C++17 filesystem 文件系統(tǒng)(詳解)
java開發(fā)中有關(guān)mian函數(shù)的一些疑問
jar參數(shù)運(yùn)行應(yīng)用時(shí)classpath的設(shè)置方法
一個(gè)Java程序的執(zhí)行過程
java動(dòng)態(tài)加載指定的類或者jar包反射調(diào)用其方法
學(xué)習(xí)Spring必學(xué)的Java基礎(chǔ)知識(shí)(1)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服