tomcat启动时很重要的是使用了自己定义的一个类加载器,对于该类加载器的源码稍微做一个简单的了解。
tomcat 版本是7.0.33。
在Bootstrap的initClassLoaders方法中,即是对类加载器的实例化过程。
特别说明一下commonLoader的加载过程,首先查找catalina.properties中是否有common.loader的配置项,如有,则将该值作为类加载需要加载的路径。
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
接下来就是替换掉其中的catalina.base, catalina.home,在我的环境中,这2项都是D:apache-tomcat-7.0.33
替换之后就是:D:/apache-tomcat-7.0.33/lib,D:/apache-tomcat-7.0.33/lib/*.jar,D:apache-tomcat-7.0.33/lib,D:apache-tomcat-7.0.33/lib/*.jar
接下来就是由逗号分割,逐项加入repositories列表。
// Local repository if (repository.endsWith("*.jar")) { repository = repository.substring (0, repository.length() - "*.jar".length()); repositories.add( new Repository(repository, RepositoryType.GLOB)); } else if (repository.endsWith(".jar")) { repositories.add( new Repository(repository, RepositoryType.JAR)); } else { repositories.add( new Repository(repository, RepositoryType.DIR)); }
这些列表存在重复项,且有几种不一样的类型,DIR,GLOB,JAR,URL,在处理方式上也有不同。
DIR:
将该路径作为一个目录处理,生成一个URL对象,添加到加载项集合。
File directory = new File(repository.getLocation()); directory = directory.getCanonicalFile(); if (!validateFile(directory, RepositoryType.DIR)) { continue; } URL url = directory.toURI().toURL(); if (log.isDebugEnabled()) log.debug(" Including directory " + url); set.add(url);
JAR
该路径就是一个简单的文件路径,生成一个URL对象,直接加到加载项集合。
GLOB
则该路径是一个目录,将该目录下所有jar文件,分别生成一个URL对象,添加到加载项集合。
URL
直接添加。
最后new StandardClassLoader(array); 就完成类加载器的实例化。