tomcat啟動(二)org.apache.catalina.startup.Bootstrap分析


/**
 * 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM