TOMCAT-02-tomcat 啓動流程01

tomcat 啓動流程01

經過debug 分析tomcat啓動流程java

1.tomcat啓動入口

clipboard.png

二、初始化Catalina對象

1. 初始化內容:反射實例話Catalina並添加ClassLoaderapache

初始化入口bootstrap

public static void main(String args[]) {//args 參數是start, stop 等等

        if (daemon == null) {
            // Don't set daemon until init() has completed
            Bootstrap bootstrap = new Bootstrap();
            try {
                bootstrap.init();//初始化Catalina對象,參考catalinaDaemon

bootstrap.init會初始化一個Catalina對象,並給其中的ClassLoader賦值tomcat

classLoader成員變量學習

/**
     * The shared extensions class loader for this server.
     */
    protected ClassLoader parentClassLoader =Catalina.class.getClassLoader();

二、初始化Catalina的classloaderthis

//tomcat 的3個相關classloader
    ClassLoader commonLoader = null;
    ClassLoader catalinaLoader = null;
    ClassLoader sharedLoader = null;


    // -------------------------------------------------------- Private Methods
    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);

上述initClassLoaders方法會讀取${TOMCAT_HOME}/conf/catalina.properties文件,讀取要loader的jar包配置spa

clipboard.png

注意,tomcat在catalina.properties 配置文件中指定了:common.loader,catalina.loader,shared.loader可是後2者的配置都爲空,網上說是shared.loader 是分享公共的,沒有配置的意義。
從上述的initClassLoaders 能夠看出使用creatteClassLoader("","") 建立後二者的loader時,都傳入了commonLoader, 這樣,配置爲空,catalinaLoader 其實仍是commonLoader.debug

備註:tomcat使用了org.apache.catalina.startup.CatalinaProperties封裝tomcat/conf/catalina.properties文件,其讀取配置文件的方式值得學習,代碼以下:code

private static void loadProperties() {

        InputStream is = null;
        Throwable error = null;

        try {
            String configUrl = System.getProperty("catalina.config");
            if (configUrl != null) {
                is = (new URL(configUrl)).openStream();
            }
        } catch (Throwable t) {
            handleThrowable(t);
        }

        if (is == null) {
            try {
                File home = new File(Bootstrap.getCatalinaBase());
                File conf = new File(home, "conf");
                File propsFile = new File(conf, "catalina.properties");

學習之處:能夠看到,第一步是判斷有沒有catalina.config 指定catalina.conf的配置路徑,沒有該-D參數纔會使用tomcat/conf下的該配置。這個值得學習。server

三、反射建立Catalina對象,並設置classLoader

public void init() throws Exception {

        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.getConstructor().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;

    }

三、設置Catalina對象爲BootStrap的catalinaDaemon 成員變量

private Object catalinaDaemon = null;  //catalinaDaemon 是Catalina對象,該對象的parentClassLoader 屬性是sharedClassloader 也就是commonClassLoader

咱們能夠看到,其中的catalinaDaemon 的聲明是Object類型的,下降了tomcat和Catalina的耦合,並且編譯Bootstrap時不用提供Catalina的依賴。

相關文章
相關標籤/搜索