`
wezly
  • 浏览: 485281 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Tomcat研究之ClassLoader

阅读更多

在研究Tomcat 之前,一般是借用现有的UML工具分析Tomcat整体结构,但要分析Tomcat的流程就必须从分析Tomcat的StartUp入手。Tomcat的启动是从解析bat文件开始,bat文件最终调用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,执行Main方法

2. $JAVA_HOME/lib/tools.jar  Sun的工具类,包括编译Jsp为Servlet的工具类

   - Common       这个目录下的类虽然对TOMCAT和所有的WEB APP都可见.但是Web App的类不应该

                    放在这个目录下,所有未打包的Class都在$CATALINA_HOME/common/classes下,所

                    有打包的jar都在

                    $CATALINA_HOME/commons/endorsed和$CATALINA_HOME/common/lib下,默认情况会

                    包含以下几个包:

                    1. jndi.jar JNDI API接口,这个包仅在Java1.2时候装入,1.3以后的版本JDK已

                    自动装入.

                    2. naming-common.jar JNDI接口实现类,Tomcat用这些类在内存中使用Context.

                    3. naming-resources.jar JNDI实现,Tomcat用它们定位Web App的静态资源.

                    4. servlet.jar Servlet,Jsp API

                    5. xerces.jar XML解析器,特定的Web App可以在自己的/WEB-INF/lib 中覆盖.

 

      - Catalina   装入Tomcat实现所有接口的类,这些类对Web App是完全不可见 的,所有未打包的类在

                    $CATALINA_HOME/server/classes所有jar包在$CATALINA_HOME/server/lib下.一

                    般情况该ClassLoader将Load下面几个包:

                    1. catalina.jar Servlet容器的Tomcat实现包

                    2. jakarta-regexp-X.Y.jar 正则表达式,请求过滤时使用

                    3. servlets-xxxxx.jar Servlet支持包

                    4 . tomcat-coyote.jar Tomcat的Coyote连接实现包

                    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都可见的类,对TOMCAT不可见. 所有未打包的类在

                    $CATALINA_HOME/shared/classes所有jar包在$CATALINA_HOME /lib下.

                    默认情况包含下面几个包:

                    1. jasper-compiler.jar Jsp编译器,编译Jsp为Servlet

                    2. jasper-runtime.jar Jsp(已编译成Servlet)运行支持包

                    3. naming-factory.jar 支持Web App使用JNDI的封装包

     -WebAppX   Web App ClassLoader,当Web App被部署是该ClassLoader被创建.所有class都在

                    WEB-INF/classes下,所有jar在WEB-INF/lib下.

   

  特别注意WEB APP自己的ClassLoader的实现与众不同:

  它先试图从WEB APP自己的目录里载入,如果失败则请求父ClassLoader的代理

  这样可以让不同的WEB APP之间的类载入互不干扰.另,Tomcat Server使用的是Catalina    

  ClassLoader,一般的Web App使用的是WebApp ClassLoader.

二. org.apache.catalina.startup.Bootstrap

          该类是Tomcat的执行入口点,我们着重分析下面两个方法:

          1. initClassLoaders,创建ClassLoader层次.

            

private void initClassLoaders() { 

                try { 

                          ClassLoaderFactory.setDebug(debug); 

                          //创建common ClassLoader,没有父ClassLoader 

                          commonLoader = createClassLoader("common", null); 

  

                          //创建catalina ClassLoader,父ClassLoader为common 

                          catalinaLoader = createClassLoader("server", commonLoader); 

  

                          //创建shared ClassLoader, 父ClassLoader为common 

                          sharedLoader = createClassLoader("shared", commonLoader); 

                       } catch (Throwable t) { 

                          log("Class loader creation threw exception", t); 

                          System.exit(1); 

                      } 

              } 

           2. createClassLoader,负责具体的创建工作

             在$CATALINA_HOME/conf/catalina.properties中定义了common, server, shared

             ClassLoader载入类的路径及一些包的安全权限.

         

              //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,一般是一个目录 

          *2.打包的jar目录 

          *3.网络资源,一般是网上的一个jar包 (Applet经常用到这样的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(); 

          //网络路径指定的包 

      ArrayList urlList = new ArrayList(); 

  

            StringTokenizer tokenizer = new StringTokenizer(value, ","); 

             

             //当前Loader该装载的类 

               while (tokenizer.hasMoreElements()) { 

                    String repository = tokenizer.nextToken(); 

                    // Check for a JAR URL repository 

            try { 

                //如果是网络路径追加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()); 

                    } 

                    /**经过上述操作,把catalina.properties里的路径替换成绝对路径*/ 

            

           //如果是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]); 

  

        //调用Factory的方法创建ClassLoader 

        return ClassLoaderFactory.createClassLoader 

            (unpacked, packed, urls, parent); 

    } 



 
三. ClassLoaderFactory

          ClassLoaderFactory是用于创建ClassLoader的工厂类,这个类比较简单.

         

//参数含义不再说明,参看上面的分析

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目录构造file协议的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文件,逐一构造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()); 

                } 

            } 

        } 

  

        //追加网络路径的资源 

        if (urls != null) { 

            for (int i = 0; i < urls.length; i++) { 

                list.add(urls[i].toString()); 

            } 

        } 

  

        //调用StandardClassLoader创建实际的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类具有从硬盘目录装载类,或从本地或远程装载jar文件的能力.这个类也实现了Reloader接口,提供了自动重新装载类的功能.我们主要看这个类以下及个方法:

1.      构造函数StandardClassLoader

   /** 

     * @param repositories url数组,见上分析 

     * @param parent 父loader 

      */ 

    public StandardClassLoader(String repositories[], ClassLoader parent) { 

        //调用父类的构造函数 

        //父类的构造函数将用转换后的repositories生成URLClassPath的实例 

        //ucp是类成员变量ucp= new URLClassPath(urls); 

       // URLClassPath是sun的扩展包,无法继续跟踪 

        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); 

  

        // 当前url是指向本地或网路的jar文件,验证jar的正确性 

          //下面的代码看似无用其实是在验证jar文件的正确性,如果jar文件错误抛异常中止执行. 

        if (!repository.endsWith(File.separator) && !repository.endsWith("/")) { 

            JarFile jarFile = null; 

            try { 

                Manifest manifest = null; 

  

                //jar协议 

                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协议 

                } 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(); 

  

                //其他情况均为错误 

                } else { 

                    throw new IllegalArgumentException 

                        ("addRepositoryInternal:  Invalid URL '" + 

                         repository + "'"); 

                } 

            } catch (Throwable t) { 

                t.printStackTrace(); 

                throw new IllegalArgumentException 

                    ("addRepositoryInternal: " + t); 

            } finally { 

                if (jarFile != null) { 

                    try { 

                        jarFile.close(); 

                    } catch (Throwable t) {} 

                } 

            } 

        } 

  

        //增加当前的url到系统内部的url列表 

        synchronized (repositories) { 

            String results[] = new String[repositories.length + 1]; 

            System.arraycopy(repositories, 0, results, 0, repositories.length); 

            results[repositories.length] = repository; 

            repositories = results; 

        } 

    } 

 repositories是一个类变量,存放着所有的url列表.

 

通过这个方法我们基本可以确定几点:

1.      ClassLoader可以把一个以”/”或File.separator结尾的路径作为装载类的资源

2.      也可以把本地或网路上的jar文件作为装入class的资源,其他任何形式的资源(比如zip)都是不合法的.

3.      网络上的资源必须是jar包的形式

到此,ClassLoader的构造结束.
3.loadClass方法

          上面我们做了很多的工作,目的是构建一个classLoader,构建ClassLoader的目的是用它load想要的class,因此loadClass方法才是我们的重心,同时通过它可以彻底解开ClassLoader的神秘面纱.

   

 /** 

      *param name:要load的类名 

      *param resolve:如果是true将调用resolveClass 

     */ 

    public Class loadClass(String name, boolean resolve) 

        throws ClassNotFoundException { 

  

        if (debug >= 2) 

            log("loadClass(" + name + ", " + resolve + ")"); 

        Class clazz = null; 

  

        //检查缓存,看是否类已经被load 

        clazz = findLoadedClass(name); 

        if (clazz != null) { 

            if (debug >= 3) 

                log("  Returning class from cache"); 

            if (resolve) 

                resolveClass(clazz); 

            return (clazz); 

        } 

  

        // 如果是java包用系统ClassLoader取load 

        if( name.startsWith("java.") ) { 

            ClassLoader loader = system; 

            clazz = loader.loadClass(name); 

            if (clazz != null) { 

                if (resolve) 

                    resolveClass(clazz); 

                return (clazz); 

            } 

            throw new ClassNotFoundException(name); 

        } 

  

        // 检查是否有权限对该类对应的包做load,包的load权限在catalina.properties里定义 

        if (securityManager != null) { 

            int i = name.lastIndexOf('.'); 

            if (i >= 0) { 

                try { 

                     securityManager.checkPackageAccess(name.substring(0,i)); 

                } catch (SecurityException se) { 

                    String error = "Security Violation, attempt to use " + 

                        "Restricted Class: " + name; 

                     System.out.println(error); 

                    se.printStackTrace(); 

                    log(error); 

                    throw new ClassNotFoundException(error); 

                } 

            } 

        } 

  

        //该类是否委派给父ClassLoader去装载 

        if (delegate) { 

            if (debug >= 3) 

                log("  Delegating to parent classloader"); 

            ClassLoader loader = parent; 

            if (loader == null) 

                loader = system; 

            try { 

                clazz = loader.loadClass(name); 

                if (clazz != null) { 

                    if (debug >= 3) 

                        log("  Loading class from parent"); 

                    if (resolve) 

                        resolveClass(clazz); 

                    return (clazz); 

                } 

            } catch (ClassNotFoundException e) { 

                ; 

            } 

        } 

  

        //从本地装载该类 

        if (debug >= 3) 

            log("  Searching local repositories"); 

        try { 

            //调用Tomcat实现ClassLoader的核心方法去寻找类 

            clazz = findClass(name); 

            if (clazz != null) { 

                if (debug >= 3) 

                    log("  Loading class from local repository"); 

                if (resolve) 

                    resolveClass(clazz); 

                return (clazz); 

            } 

        } catch (ClassNotFoundException e) { 

            ; 

        } 

  

        //如果该类没有被委派到父类,则用系统loader去装载 

            if (debug >= 3) 

                log("  Delegating to parent classloader"); 

            ClassLoader loader = parent; 

            if (loader == null) 

                loader = system; 

            try { 

                clazz = loader.loadClass(name); 

                if (clazz != null) { 

                    if (debug >= 3) 

                        log("  Loading class from parent"); 

                    if (resolve) 

                        resolveClass(clazz); 

                    return (clazz); 

                } 

            } catch (ClassNotFoundException e) { 

                ; 

            } 

        } 

  

        // This class was not found 

        throw new ClassNotFoundException(name); 

  

    } 

 4.      findClass方法

public Class findClass(String name) throws ClassNotFoundException { 

  

        if (debug >= 3) 

            log("    findClass(" + name + ")"); 

  

        // 检查包的定义,我们不对此处做深究可略过 

        if (securityManager != null) { 

            int i = name.lastIndexOf('.'); 

            if (i >= 0) { 

                try { 

                    if (debug >= 4) 

                        log("      securityManager.checkPackageDefinition"); 

                     securityManager.checkPackageDefinition(name.substring(0,i)); 

                } catch (Exception se) { 

                    if (debug >= 4) 

                        log("      -->Exception-->ClassNotFoundException", se); 

                    throw new ClassNotFoundException(name); 

                } 

            } 

        } 

        // 如果在本地不能地位类则请求父类加载 

        // (throws ClassNotFoundException if it is not found) 

        Class clazz = null; 

        try { 

            if (debug >= 4) 

                log("      super.findClass(" + name + ")"); 

            try { 

                synchronized (this) {                              

                    clazz = findLoadedClass(name); 

                    if (clazz != null) 

                        return clazz; 

                   //请求父类加载 

                     clazz = super.findClass(name); 

                } 

            } catch(AccessControlException ace) { 

                throw new ClassNotFoundException(name); 

            } catch (RuntimeException e) { 

                if (debug >= 4) 

                    log("      -->RuntimeException Rethrown", e); 

                throw e; 

            } 

            if (clazz == null) { 

                if (debug >= 3) 

                    log("    --> Returning ClassNotFoundException"); 

                throw new ClassNotFoundException(name); 

            } 

        } catch (ClassNotFoundException e) { 

            if (debug >= 3) 

                log("    --> Passing on ClassNotFoundException", e); 

            throw e; 

        } 

        // Return the class we have located 

        if (debug >= 4) 

            log("      Returning class " + clazz); 

        if ((debug >= 4) && (clazz != null)) 

            log("      Loaded by " + clazz.getClassLoader()); 

        return (clazz); 

  

    } 

  

5.      父类(URLClassLoader)的findClass方法

      前面我们曾经说过,URLClassLoader具有从本地装载class,从本地或网络装载jar的功能.

简单说findClass方法只是简单地调用了PrivilegedExceptionAction的run方法,关于这个类我们不必细致了解,只需看下面打蓝色的部分就可以了.

 

    protected Class findClass(final String name) throws ClassNotFoundException   { 

      try { 

          return (Class) 

                AccessController.doPrivileged(new PrivilegedExceptionAction() { 

                    public Object run() throws ClassNotFoundException { 

                           //将类名替换成硬盘绝对路径 

                           String path = name.replace('.', '/').concat(".class"); 

                           //关于ucp类变量的说明见上面 

                           //该调用主要是把本地的class文件转换成Resource(不考虑转换细节) 

                           Resource res = ucp.getResource(path, false); 

                           if (res != null) { 

                               try { 

                                     //通过类名与类的Resource生成Class 

                                     return defineClass(name, res); 

                               } catch (IOException e) { 

                                     throw new ClassNotFoundException(name, e); 

                               } 

                           } else { 

                               throw new ClassNotFoundException(name); 

                           } 

                    } 

                }, acc); 

      } catch (java.security.PrivilegedActionException pae) { 

          throw (ClassNotFoundException) pae.getException(); 

      } 

    } 

 6 . defineClass方法

      该方法主要是调用JVM的native方法构建一个class对象,关于这个类的细节我们没必要很清除,我们要知道的是JVM利用Resource构造了Class对象.我们只需关注下面蓝色的部分.

  

    /** 

        *param name:类名 

        *param res:这个参数是通过ucp变量得到,ucp是通过我们传入的url构建,url就是 

        *ClassLoader Load Class 的路径 

        *换句话说我们辛苦构造的StandClassLoader就是为了得到Resource 

        *Resource是JVM用来构造Class必须条件 

        */ 

    private Class defineClass(String name, Resource res) throws IOException { 

      int i = name.lastIndexOf('.'); 

      URL url = res.getCodeSourceURL(); 

      if (i != -1) { 

          String pkgname = name.substring(0, i); 

          // Check if package already loaded. 

          Package pkg = getPackage(pkgname); 

          Manifest man = res.getManifest(); 

          if (pkg != null) { 

                // Package found, so check package sealing. 

                if (pkg.isSealed()) { 

                    // Verify that code source URL is the same. 

                    if (!pkg.isSealed(url)) { 

                           throw new SecurityException( 

                               "sealing violation: package " + pkgname + " is sealed"); 

                    } 

  

                } else { 

                    // Make sure we are not attempting to seal the package 

                    // at this code source URL. 

                    if ((man != null) && isSealed(pkgname, man)) { 

                           throw new SecurityException( 

                               "sealing violation: can't seal package " + pkgname + 

                               ": already loaded"); 

                    } 

                } 

          } else { 

                if (man != null) { 

                    definePackage(pkgname, man, url); 

                } else { 

                    definePackage(pkgname, null, null, null, null, null, null, null); 

                } 

          } 

      } 

      //下面是JVM通过二进制代码构造一个Class 

      byte[] b = res.getBytes(); 

      java.security.cert.Certificate[] certs = res.getCertificates(); 

      CodeSource cs = new CodeSource(url, certs); 

      return defineClass(name, b, 0, b.length, cs); 

    } 

    至此,我们彻底破译了Tomcat的ClassLoader,下面我们再画一下ClassLoader的构造及loadClass的过程.这里不再画 sequence图,只是简单表示一下各方法之间的调用关系.其实,从上面我们可以看出真正起到创建ClassLoader关键作用的是 URLClassLoader和JVM的defineClass方法,这些方法已被封装或是本地调用,要进一步研究就需要花费更多的精力.阅读了这个流程后相信每人都能定制出自己需要的ClassLoader,比如加密ClassLoader.

BootsStrap

 
 
createClassLoader ( 构造三种 url,)
 
initClassLoaders ( 初 始化三个 ClassLoader )

 
 
ClassLoaderFactory
 
createClassLoader ( 构造带协议的 , 真正的 url)
 
StandardClassLoader

 
loadClass
 
findClass 查询类
 
URLClassLoader
 
findClass
 
defineClass
 

 

参考资料:

     http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html

备注:

     本文所讲解的Tomcat是以5.0为基础的.

 

分享到:
评论

相关推荐

    Tomcat研究之ClassLoader.pdf

    ### Tomcat中的ClassLoader详解 #### 一、引言 在深入了解Tomcat的工作原理时,一个重要的组成部分就是其ClassLoader机制。本文旨在深入剖析Tomcat中特有的类加载器(ClassLoader)体系结构,帮助读者理解Tomcat...

    Tomcat 5.0.18 ClassLoader source code insight

    总的来说,深入研究Tomcat 5.0.18的ClassLoader源码,不仅可以提升我们的技术水平,还能让我们更好地应对Java Web开发中的挑战。对于那些想要深入理解Java类加载机制和Tomcat内部工作的开发者,这是一个不可多得的...

    tomcat 类加载机制 —— ClassLoader

    《Tomcat类加载机制——ClassLoader详解》 在Java Web开发中,Tomcat作为最常用的Servlet容器,其类加载机制对于...通过阅读和研究Tomcat源码,我们可以更深入地了解这一机制,从而更好地驾驭这个强大的Web服务器。

    Tomcat源代码学习研究

    - **Classloading**:Tomcat使用定制的ClassLoader加载Web应用的类,遵循“父类加载优先”原则。 6. **连接器与协议处理** - **NIO和Apr**:Tomcat提供了多种连接器实现,如基于Java NIO的 Coyote Connector 和...

    Tomcat:apache-tomcat-6.0.18

    5. **ClassLoader机制**:Tomcat使用自定义的ClassLoader来加载Web应用程序的类,确保不同应用之间的类隔离,防止冲突。 Tomcat 6.0.18版的特性包括: 1. **性能优化**:相对于之前的版本,6.0.18进行了性能调优,...

    tomcat类加载器

    4. Common ClassLoader:在Tomcat中,它是所有Web应用共享的类加载器,用于加载`common.loader`配置项指定的类路径。 5. WebApp ClassLoader:每个Web应用有自己的类加载器,它加载应用的`WEB-INF/classes`和`WEB-...

    tomcat 学习与分析总结资料

    通过研究这个脚本,我们可以了解如何配置JVM参数,如内存分配、堆大小以及设置系统属性,以优化Tomcat的性能。 2. **Tomcat工作原理** Tomcat基于Coyote和Apr(Apache Portable Runtime)处理HTTP请求。Coyote是...

    深入剖析Tomcat 随书 源码

    《深入剖析Tomcat》这本书是Java开发者们探索Tomcat服务器内部机制的重要参考资料,它带领读者逐步揭开Tomcat的...通过学习和研究Tomcat源码,我们可以提升技术水平,解决实际问题,甚至为Tomcat社区贡献自己的力量。

    Tomcat6的源码

    5. **ClassLoader机制**:Tomcat的类加载机制允许每个Web应用拥有自己的类加载器,避免类冲突。理解这部分源码对于理解和解决部署问题至关重要。 6. **Session管理**:Tomcat处理用户会话,包括创建、跟踪和管理...

    apache-tomcat-7.0.81-src 源码免费下载

    10. **网络编程**:Tomcat底层使用NIO(非阻塞I/O)和BIO(阻塞I/O)模型,这在`java/org/apache/tomcat/util/net`目录下可以深入研究。 通过学习和分析这些源码,开发者不仅可以提升对Java Web技术的理解,还可以...

    java类加载器-tomcat中的类加载器

    4. 最后,如果所有父类加载器都未能加载,Catalina ClassLoader才加载Tomcat自身的类。 VSD文件可能包含一个流程图,详细描绘了Tomcat类加载器的工作流程和关系,这对于理解类加载机制非常有帮助。通过阅读和分析该...

    apache-tomcat-7.0.40-src

    1. **Servlet和JSP标准实现**:Tomcat是Java Web应用的标准之一,它遵循Java Servlet和JSP规范。在源码中,你可以看到如何实现这些规范,包括请求处理、响应生成、会话管理以及生命周期管理。 2. **Catalina组件**...

    tomcat8源码的maven项目

    3. **学习部署和加载机制**:Tomcat如何加载和管理Web应用程序,包括WAR文件的部署和Classloader的工作原理。 4. **研究线程模型**:Tomcat如何使用线程来处理并发请求,以及线程池的配置和管理。 5. **深入JSP和...

    tomcat 6 源码

    5. **ClassLoader**:Tomcat使用自定义的ClassLoader来加载Web应用的类。这使得不同应用之间能隔离地运行,避免类冲突。 6. **Lifecycle**:所有Tomcat组件都遵循生命周期接口,如`org.apache.catalina.Lifecycle`...

    tomcat-4.1.40-src

    3. **启动流程**:Tomcat的启动过程始于`bin/catalina.sh`或`catalina.bat`,这些脚本会初始化Java环境,并加载`catalina.jar`中的`org.apache.catalina.startup.ClassLoader`,接着加载`Server`对象,初始化`...

    Tomcat7 源码Eclipse工程

    总的来说,通过研究Tomcat7的源码Eclipse工程,不仅可以提升Java Web开发的专业技能,还能深入了解服务器架构设计,这对于优化应用性能、排查故障以及定制化开发具有极大的价值。在实践中,我们可以结合官方文档和...

    apache-tomcat-源码-lib包

    源码中,ClassLoader的实现(例如`org.apache.catalina.loader.WebappClassLoaderBase`)值得深入研究。 5. **部署和配置**:Tomcat支持多种方式部署Web应用,如WAR文件、目录结构或者通过管理接口。源码中,你可以...

    tomcat_src

    在Java Web开发领域,Tomcat无疑是最为流行的开源应用服务器之一。它以其轻量级、高效和易于管理的特性赢得了广大开发者喜爱。"Tomcat_src"这个压缩包中包含的就是Apache Tomcat的源代码,这为我们深入理解其工作...

Global site tag (gtag.js) - Google Analytics