首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

tomcat6学习札记——Bootstrap、Catalina

2012-09-02 
tomcat6学习笔记——Bootstrap、Catalina前面了解过tomcat的启动脚本,Tomcat的启动是Bootstrap中的main方法pu

tomcat6学习笔记——Bootstrap、Catalina
前面了解过tomcat的启动脚本,Tomcat的启动是Bootstrap中的main方法

public static void main(String args[]) {        if (daemon == null) {            daemon = new Bootstrap();            try {                daemon.init();            } catch (Throwable t) {                t.printStackTrace();                return;            }        }                // 根据不同的命令参数执行        try {            String command = "start";            if (args.length > 0) {                command = args[args.length - 1];            }            if (command.equals("startd")) {                args[args.length - 1] = "start";                daemon.load(args);                daemon.start();            } else if (command.equals("stopd")) {                args[args.length - 1] = "stop";                daemon.stop();            } else if (command.equals("start")) {                daemon.setAwait(true);                daemon.load(args);                daemon.start();            } else if (command.equals("stop")) {                daemon.stopServer(args);            } else {                log.warn("Bootstrap: command "" + command + "" does not exist.");            }        } catch (Throwable t) {            t.printStackTrace();        }    }


首先是init()

public void init()        throws Exception    {        // Set Catalina path        // 设置catalina_home属性,tomcat启动脚本里有通过-Dcatalina.home设置        setCatalinaHome();        // 设置catalina_base属性,运行多实例的时候该目录与catalina_home不同        setCatalinaBase();        // 初始化classloader,读取conf/catalina.properties,根据指定的repository创建classloader        // 有三个classloader   分别是common、catalina、shared,tomcat6中三个相同        initClassLoaders();        // 设置当前线程的classloader        Thread.currentThread().setContextClassLoader(catalinaLoader);        // 待研究        SecurityClassLoad.securityClassLoad(catalinaLoader);        // 以下通过反射调用Catalina中的方法        // 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;    }


然后load,实际上市通过反射调用了catalina的load方法。
1、找到config file(server.xml)
2、创建digester,解析server.xml,生成各组件对象(Server、Service、Container、Connector等)以及建立相互之间的关系。

// Configure the actions we will be using        digester.addObjectCreate("Server",                                 "org.apache.catalina.core.StandardServer",                                 "className");        digester.addSetProperties("Server");        digester.addSetNext("Server",                            "setServer",                            "org.apache.catalina.Server");        digester.addObjectCreate("Server/GlobalNamingResources",                                 "org.apache.catalina.deploy.NamingResources");        digester.addSetProperties("Server/GlobalNamingResources");        digester.addSetNext("Server/GlobalNamingResources",                            "setGlobalNamingResources",                            "org.apache.catalina.deploy.NamingResources");        digester.addObjectCreate("Server/Listener",                                 null, // MUST be specified in the element                                 "className");        digester.addSetProperties("Server/Listener");        digester.addSetNext("Server/Listener",                            "addLifecycleListener",                            "org.apache.catalina.LifecycleListener");        digester.addObjectCreate("Server/Service",                                 "org.apache.catalina.core.StandardService",                                 "className");        digester.addSetProperties("Server/Service");        digester.addSetNext("Server/Service",                            "addService",                            "org.apache.catalina.Service");        digester.addObjectCreate("Server/Service/Listener",                                 null, // MUST be specified in the element                                 "className");        digester.addSetProperties("Server/Service/Listener");        digester.addSetNext("Server/Service/Listener",                            "addLifecycleListener",                            "org.apache.catalina.LifecycleListener");        //Executor        digester.addObjectCreate("Server/Service/Executor",                         "org.apache.catalina.core.StandardThreadExecutor",                         "className");        digester.addSetProperties("Server/Service/Executor");        digester.addSetNext("Server/Service/Executor",                            "addExecutor",                            "org.apache.catalina.Executor");                digester.addRule("Server/Service/Connector",                         new ConnectorCreateRule());        digester.addRule("Server/Service/Connector",                          new SetAllPropertiesRule(new String[]{"executor"}));        digester.addSetNext("Server/Service/Connector",                            "addConnector",                            "org.apache.catalina.connector.Connector");        // ...


最后start(),同样是在Bootstrap中通过反射调用catalina对象的start方法。

public void start() {        if (getServer() == null) {            load();        }        if (getServer() == null) {            log.fatal("Cannot start server. Server instance is not configured.");            return;        }        long t1 = System.nanoTime();                // Start the new server        if (getServer() instanceof Lifecycle) {            try {                ((Lifecycle) getServer()).start();            } catch (LifecycleException e) {                log.error("Catalina.start: ", e);            }        }        long t2 = System.nanoTime();        if(log.isInfoEnabled())            log.info("Server startup in " + ((t2 - t1) / 1000000) + " ms");        try {            // Register shutdown hook            if (useShutdownHook) {                if (shutdownHook == null) {                    shutdownHook = new CatalinaShutdownHook();                }                Runtime.getRuntime().addShutdownHook(shutdownHook);                                // If JULI is being used, disable JULI's shutdown hook since                // shutdown hooks run in parallel and log messages may be lost                // if JULI's hook completes before the CatalinaShutdownHook()                LogManager logManager = LogManager.getLogManager();                if (logManager instanceof ClassLoaderLogManager) {                    ((ClassLoaderLogManager) logManager).setUseShutdownHook(                            false);                }            }        } catch (Throwable t) {            // This will fail on JDK 1.2. Ignoring, as Tomcat can run            // fine without the shutdown hook.        }        if (await) {            await();            stop();        }    }

由于之间digester解析之间的push操作
    digester.push(this);
    digester.parse(inputSource);
解析时通过catalina的setServer方法将创建的StandardServer对象设置进去了,所以上面getServer方法返回digester创建的server对象,然后开始各组件的生命周期。Lifecycle、LifecycleListeners等。
Server start、通知监听器、Service start。。。

热点排行