/** * Bootstrap loader for Catalina. This application constructs a class loader * for use in loading the Catalina internal classes (by accumulating all of the * JAR files found in the "server" directory under "catalina.home"), and * starts the regular execution of the container. The purpose of this * roundabout approach is to keep the Catalina internal classes (and any * other classes they depend on, such as an XML parser) out of the system * class path and therefore not visible to application level classes.
這個類構造一個類加載器來加載Catalina內部類(通過在server目錄下的catalina.home來找到所有的jar文件),和開始定期執行container容器。
這種回旋處理方法的目的是保持Catalina內部類(以及其依賴的任何其他類,如XML解析器)脫離系統類路徑,因此對應用程序級別不可見
入口main方法
在進入main之前會前執行static靜態模塊代碼:主要是設置catalina.home和catalina.base的路徑
public static void main(String args[]) {
bootstrap初始化init()
設置守護進程daemon = bootstrap;
識別啟動bootstrap時傳遞的參數command = args[args.length - 1];//start
daemon.setAwait(true);
daemon.load(args);
daemon.start();}
上面damemon守護進程的方法setAwait(),load(),start()其實是反射調用的org.apache.catalina.startup.Catalina類的方法
到這里其實就進入到Catalina類的。
--------------------------Bootstrap類解析完畢------下面是對init方法解釋---------------------------------------------------------
初始化init方法(初始化守護進程):
在這個方法里主要流程
1、初始化類加載器initClassLoaders()----------commonLoader,catalinaLoader,sharedLoade會先加載catalina.base/conf/catalina.propertises配置文件
然后讀取common.loader鍵所對應的值
Catalina.properties文件下
common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"
補充下:
commonLoader再定義時使用ClassLoader定義,但是創建返回的是URLClassLoader。公有類定義,子類返回,這個思路值得借鑒
public class URLClassLoader extends SecureClassLoader implements Closeable
URLClassLoader繼承SecureClassLoader
public class SecureClassLoader extends ClassLoader
SecureClassLoader繼承ClassLoader
ClassLoader commonLoader = null;
ClassLoader catalinaLoader = null;
ClassLoader sharedLoader = null;
private void initClassLoaders() { try { commonLoader = createClassLoader("common", null); if( commonLoader == null ) { // no config file, default to this loader - we might be in a 'single' env. commonLoader=this.getClass().getClassLoader(); } catalinaLoader = createClassLoader("server", commonLoader); sharedLoader = createClassLoader("shared", commonLoader);
createClassLoader()
獲取common.loader鍵對應的值 String value = CatalinaProperties.getProperty(name + ".loader"); String[] repositoryPaths = getPaths(value); 。。。省略部分代碼 for (String repository : repositoryPaths) { // Check for a JAR URL repository try { @SuppressWarnings("unused") URL url = new URL(repository); repositories.add( new Repository(repository, RepositoryType.URL)); continue; } catch (MalformedURLException e) { // Ignore } // 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)); } }
return ClassLoaderFactory.createClassLoader(repositories, parent);最后調用這個方法將repositories內存放的類和資源的路徑綁定到commonLoader。這里返回的是new URLClassLoader
createClassLoader()方法獲取到
common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"
接下來會判斷這個字符串是以什么結尾
${catalina.base}/lib
${catalina.home}/lib
/lib是目錄 commonLoader會加載整個目錄下的資源,包括所有clsss、jar包及其它類型資源
${catalina.base}/lib/*.jar
${catalina.home}/lib/*.jar
表示整個目錄下所有jar包資源,僅僅是.jar后綴的資源
解釋下RepositoryType這是一個枚舉類型,定義再類org.apache.catalina.startup.ClassLoaderFactory內部
public static enum RepositoryType { DIR,表示整個目錄下的資源,包括所有clsss、jar包及其它類型資源。 GLOB,表示整個目錄下所有jar包資源,僅僅是.jar后綴的資源。 JAR,表示單個jar包資源。 URL表示網絡上得某個jar包資源 }
2、為當前線程設置classLoader
Thread.currentThread().setContextClassLoader(catalinaLoader);catalinaLoader其實就是commonLoader
用靜態類SecurityClassLoad預加載類資源
SecurityClassLoad.securityClassLoad(catalinaLoader);
securityClassLoad(ClassLoader loader, boolean requireSecurityManager) {
。。。。。略。。。。。。。。。。
loadCorePackage(loader);
loadCoyotePackage(loader);
loadLoaderPackage(loader);
loadRealmPackage(loader);
loadServletsPackage(loader);
loadSessionPackage(loader);
loadUtilPackage(loader);
loadValvesPackage(loader);
loadWebResourcesPackage(loader);
loadJavaxPackage(loader);
loadConnectorPackage(loader);
loadTomcatPackage(loader);
}
3、初始化org.apache.catalina.startup.Catalina利用反射調用它的setParentClassLoader設置sharedLoader;(設置的parentClassLoader的原因和用處暫不完全清楚,看源碼估計會在server.xml加載部分會使用到)
參考資源
Tomcat內核之類加載器工廠
具體源碼解析:http://blog.csdn.net/u011545486/article/details/52002626