码迷,mamicode.com
首页 > 其他好文 > 详细

tomcat源码分析(一)

时间:2015-02-10 21:40:34      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

tomcat的启动从Bootstrap类的main方法开始。

 public static void main(String args[]) {

        //单例
        if (daemon == null) {
            daemon = new Bootstrap();//实例化Bootstrap对象
            try {
                //实例化Catalina 并装载3个classloader,设置Catalina的父加载器
                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[0] = "start";
                daemon.load(args);
                daemon.start();
            } else if (command.equals("stopd")) {
                args[0] = "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();
        }

    }

 

/**
     * 一些初始化工作  初始化一个守护线程
     * Initialize daemon.
     */
    public void init()
        throws Exception
    {

        // Set Catalina path 初始化Tomcat的安装路径 home\base
        setCatalinaHome();
        setCatalinaBase();

        initClassLoaders();//初始化变量classloader:catalinaloader、commonloader、sharedloader  三个加载器
        
        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();//得到了Catalina的实例

        // 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);//利用反射调用Catalina的setParentClassLoader方法 设置共享扩展类装入器

        catalinaDaemon = startupInstance;  //得到Catalina的实例
}

 

 private void load(String[] arguments)
        throws Exception {

        // Call the load() method
        String methodName = "load";
        Object param[];
        Class paramTypes[];
        if (arguments==null || arguments.length==0) {
            paramTypes = null;
            param = null;
        } else {
            paramTypes = new Class[1];
            paramTypes[0] = arguments.getClass();
            param = new Object[1];
            param[0] = arguments;
        }
        Method method = 
            catalinaDaemon.getClass().getMethod(methodName, paramTypes);
        if (log.isDebugEnabled())
            log.debug("Calling startup class " + method);//利用反射调用Catalina的load方法
        method.invoke(catalinaDaemon, param);

    }

 

Catalina的load方法。主要是解析conf下的service.xml文件

    public void load() {

        long t1 = System.nanoTime();

        initDirs();//System.setPropertity("catalina.home")和catalina.home  设置系统目录

        // Before digester - it may be needed
        
        initNaming();//设置propertity  naming

        // Create and execute our Digester
        Digester digester = createStartDigester();

        InputSource inputSource = null;
        InputStream inputStream = null;
        File file = null;
        try {
            file = configFile();//读取con/server.xml的配置文件
            inputStream = new FileInputStream(file);
            inputSource = new InputSource("file://" + file.getAbsolutePath());
        } catch (Exception e) {
            ;
        }
        if (inputStream == null) {
            try {
                inputStream = getClass().getClassLoader()
                    .getResourceAsStream(getConfigFile());
                inputSource = new InputSource
                    (getClass().getClassLoader()
                     .getResource(getConfigFile()).toString());
            } catch (Exception e) {
                ;
            }
        }

        // This should be included in catalina.jar
        // Alternative: don‘t bother with xml, just create it manually.
        if( inputStream==null ) {
            try {
                inputStream = getClass().getClassLoader()
                .getResourceAsStream("server-embed.xml");
                inputSource = new InputSource
                (getClass().getClassLoader()
                        .getResource("server-embed.xml").toString());
            } catch (Exception e) {
                ;
            }
        }
        

        if ((inputStream == null) && (file != null)) {
            log.warn("Can‘t load server.xml from " + file.getAbsolutePath());
            return;
        }

        try {
            inputSource.setByteStream(inputStream);
            digester.push(this);
            digester.parse(inputSource);
            inputStream.close();
        } catch (Exception e) {
            log.warn("Catalina.start using "
                               + getConfigFile() + ": " , e);
            return;
        }

        // Stream redirection
        initStreams();

        // Start the new server
        if (server instanceof Lifecycle) {
            try {
                server.initialize();
            } catch (LifecycleException e) {
                log.error("Catalina.start", e);
            }
        }

        long t2 = System.nanoTime();
        if(log.isInfoEnabled())
            log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms");

    }

 

tomcat从Catalina的start方法开启了。

 public void start() {

        if (server == null) {
            load();
        }

        long t1 = System.nanoTime();
        
        // Start the new server
        if (server instanceof Lifecycle) {
            try {
                ((Lifecycle) server).start();//这里的server是StandardService,在这里启动服务。
            } 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);
            }
        } catch (Throwable t) {
            // This will fail on JDK 1.2. Ignoring, as Tomcat can run
            // fine without the shutdown hook.
        }

        if (await) {
            await();
            stop();
        }

    }

 

public void start() throws LifecycleException {

        // Validate and update our current component state
        if (log.isInfoEnabled() && started) {
            log.info(sm.getString("standardService.start.started"));
        }
        
        if( ! initialized )
            init(); 

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
        if(log.isInfoEnabled())
            log.info(sm.getString("standardService.start.name", this.name));
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;

    //下面的都是从conf/service.xml文件中读取到的配置信息包括:contanier,executors和connectors对应的是StandardEngine,Connector,
// Start our defined Container first if (container != null) { synchronized (container) { if (container instanceof Lifecycle) { ((Lifecycle) container).start(); } } } synchronized (executors) { for ( int i=0; i<executors.size(); i++ ) { executors.get(i).start(); } } // Start our defined Connectors second synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { if (connectors[i] instanceof Lifecycle) ((Lifecycle) connectors[i]).start(); } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }

 

tomcat源码分析(一)

标签:

原文地址:http://www.cnblogs.com/hjy9420/p/4284908.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!