Tomcat學習之啟動過程

來源:互聯網
上載者:User
startup.bat

當我們啟動tomcat一般是運行%TOMCAT_HOME%\bin\startup.bat檔案,這個檔案實際上調用了%TOMCAT_HOME%\bin\catalina.bat批次檔:

set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"......set CMD_LINE_ARGS=:setArgsif ""%1""=="""" goto doneSetArgsset CMD_LINE_ARGS=%CMD_LINE_ARGS% %1shiftgoto setArgs:doneSetArgscall "%EXECUTABLE%" start %CMD_LINE_ARGS%
startup.bat將start命令和控制台的所有參數都傳給了catalina.bat檔案,下面來看catalina.bat檔案中是怎麼啟動Tomcat的。注意到下面這句
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%

_EXECJAVA=_RUNJAVA="%JRE_HOME%\bin\java",這是在%TOMCAT_HOME%\bin\setclasspath.bat檔案中設定的,也就是說這句要運行一個JAVA程式,後面緊接著就應該是啟動並執行類%MAINCLASS%,MAINCLASS=org.apache.catalina.startup.Bootstrap,不錯org.apache.catalina.startup.Bootstrap類正是Tomcat的入口類,Tomcat正是從Bootstrap類的main方法開始啟動並執行。


Bootstrap

下面來看看Bootstrap的main方法做了哪些事情:

 public static void main(String args[]) {if (daemon == null) {Bootstrap bootstrap = new Bootstrap();try {bootstrap.init();} catch (Throwable t) {handleThrowable(t);t.printStackTrace();return;}daemon = bootstrap;}try {   ...if (command.equals("start"))   daemon.start();   ...} catch (Throwable t) {...}}
從以上代碼可以看出main方法做了3件事情:

1、初始化;

2、裝配tomcat容器

3、啟動tomcat容器


初始化

    public void init()        throws Exception    {        // Set Catalina path        setCatalinaHome();        setCatalinaBase();        initClassLoaders();        Thread.currentThread().setContextClassLoader(catalinaLoader);        SecurityClassLoad.securityClassLoad(catalinaLoader);        // Load our startup class and call its process() method        if (log.isDebugEnabled())            log.debug("Loading startup class");        Class<?> startupClass =            catalinaLoader.loadClass            ("org.apache.catalina.startup.Catalina");        Object startupInstance = startupClass.newInstance();        // Set the shared extensions class loader        if (log.isDebugEnabled())            log.debug("Setting startup class properties");        String methodName = "setParentClassLoader";        Class<?> paramTypes[] = new Class[1];        paramTypes[0] = Class.forName("java.lang.ClassLoader");        Object paramValues[] = new Object[1];        paramValues[0] = sharedLoader;        Method method =            startupInstance.getClass().getMethod(methodName, paramTypes);        method.invoke(startupInstance, paramValues);        catalinaDaemon = startupInstance;    }
1、設定catalina.home系統屬性 如果catalina.home被設定過直接返回,否則設定:如果bootstrap.jar檔案存在,就設定為這個檔案所在目錄的上一級目錄;如果不存在就設定為當前工作目錄。在%TOMCAT_HOME%\bin目錄下實際上是有這個jar檔案的,也就是catalina.home=%TOMCAT_HOME%。 2、設定catalina.base系統屬性,和1差不多 3、initClassLoaders,初始化三個classLoader: commonLoader:用於載入common/lib目錄下的jar包和class檔案
catalinaLoader:用於載入server/lib目錄下的jar包和class檔案
sharedLoader:用於載入shared/lib目錄下的jar包和class檔案 commonLoader是catalinaLoader和sharedLoader的parent classloader,Tomcat6以後,查看catalina.properties檔案可以看見server.loader和shared.loader都是為空白的。 catalina.properties檔案中common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
4、然後設定當前線程的classloader為catalinaLoader 5、緊接著載入與安全相關的包和類 6、然後設定org.apache.catalina.startup.Catalina這個類的parent classloader為sharedLoader 7、建立org.apache.catalina.startup.Catalina這個類的執行個體並賦給catalinaDaemon
裝配容器 通過調用org.apache.catalina.startup.Catalina的load方法來實現的
public void load() {initDirs();// Before digester - it may be neededinitNaming();// Create and execute our DigesterDigester digester = createStartDigester();digester.push(this);digester.parse(inputSource);getServer().init();}}
1、初始化目錄和命名規則,為digester解析XML做準備,digester準備後面再研究一下 2、建立一個digester對象,解析conf/server.xml檔案,在解析server.xml的過程中會調用StandardService.setContainer方法,將其設定為StandardEngine 3、初始化Servlet視窗,這裡的getServer()實際上返回的是StandardServer對象,這個初始化過程是在StandardServer類的initInternal方法中完成的,這個方法主要幹了兩件事,1是註冊MBean,讓JMX管理tomat容器,2是初始化Service
        // Initialize our defined Services        for (int i = 0; i < services.length; i++) {            services[i].init();        }
從代碼可以看出,一個tomcat容器是可以同時服務於多個應用的,tomcat配置多個services可以參考 http://www.ff-bb.cn/logs/109466274.html service的初始化是在StandardService類的initInternal方法中完成的
protected void initInternal() throws LifecycleException {        if (container != null) {            container.init();        }        // Initialize any Executors        for (Executor executor : findExecutors()) {            if (executor instanceof LifecycleMBeanBase) {                ((LifecycleMBeanBase) executor).setDomain(getDomain());            }            executor.init();        }        // Initialize our defined Connectors        synchronized (connectors) {            for (Connector connector : connectors) {                    connector.init();            }        }    }
這個方法也做了幾件事,1是初始化container,會調用StandardEngine的initInternal方法,2初始化Executor,3是初始化兩個連接器[Connector[HTTP/1.1-8080], Connector[AJP/1.3-8009]]
啟動容器 此處的start調用的是org.apache.catalina.startup的start方法
public void start() {...long t1 = System.nanoTime();// Start the new servertry {getServer().start();} catch (LifecycleException e) {log.error("Catalina.start: ", e);}...if (await) {await();stop();}}
start方法會調用StandardServer、StandardService、StandardEngine、StandardHost、StandardContext、StandardWrapper的start或者startInternal方法來完成啟動過程,最後會迴圈等待,在關閉命令到來之前一直運行!
總結

1、tomcat中大量引入了模板方法模式,org.apache.catalina.util.LifecycleBase被所有容器繼承,其中initInternal和startInternal方法是抽象方法,在初始化和啟動時被每個容器會調用其init和start方法,這兩個方法會去調用對應抽象方法***Internal,這些抽象方法都是在子類中實現的
2、tomcat中大量使用了類的反射,基本上都是通過設定檔擷取類名,然後利用反射得到class對象,再通過newInstance擷取對象。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.