读书人

Tomcat源码-器皿启动六(3)

发布时间: 2012-10-19 16:53:37 作者: rapoo

Tomcat源码---容器启动六(3)

一,容器已经启动到部暑文件(webapps),接下去是StandardContext,standardWarpper还有Connector等的启动

我们来了解一下部暑war文件

?

?? // Deploy WARs, and loop if additional descriptors are found

       //appBase:webapps File appBase.list:所存放的工程        deployWARs(appBase, appBase.list());

? /**

?

     * Deploy WAR files.     */    protected void deployWARs(File appBase, String[] files) {                if (files == null)            return;                for (int i = 0; i < files.length; i++) {                        if (files[i].equalsIgnoreCase("META-INF"))                continue;            if (files[i].equalsIgnoreCase("WEB-INF"))                continue;            File dir = new File(appBase, files[i]);            if (files[i].toLowerCase().endsWith(".war") && dir.isFile()) {                                // Calculate the context path and make sure it is unique                String contextPath = "/" + files[i].replace('#','/');                int period = contextPath.lastIndexOf(".");                if (period >= 0)                    contextPath = contextPath.substring(0, period);                if (contextPath.equals("/ROOT"))                    contextPath = "";                                if (isServiced(contextPath))                    continue;                                String file = files[i];                //以上是对每一个工程名以及路径进行解析                //这一步才进行部暑                deployWAR(contextPath, dir, file);                            }                    }            }

? /**

     * @param contextPath     * @param war     * @param file     */    protected void deployWAR(String contextPath, File war, String file) {                if (deploymentExists(contextPath))            return;                // Checking for a nested /META-INF/context.xml        JarFile jar = null;        JarEntry entry = null;        InputStream istream = null;        BufferedOutputStream ostream = null;        File xml = new File            (configBase, file.substring(0, file.lastIndexOf(".")) + ".xml");        if (deployXML && !xml.exists()) {            try {                jar = new JarFile(war);                entry = jar.getJarEntry(Constants.ApplicationContextXml);                if (entry != null) {                    istream = jar.getInputStream(entry);                                        configBase.mkdirs();                                        ostream =                        new BufferedOutputStream                        (new FileOutputStream(xml), 1024);                    byte buffer[] = new byte[1024];                    while (true) {                        int n = istream.read(buffer);                        if (n < 0) {                            break;                        }                        ostream.write(buffer, 0, n);                    }                    ostream.flush();                    ostream.close();                    ostream = null;                    istream.close();                    istream = null;                    entry = null;                    jar.close();                    jar = null;                }            } catch (Exception e) {                // Ignore and continue                if (ostream != null) {                    try {                        ostream.close();                    } catch (Throwable t) {                        ;                    }                    ostream = null;                }                if (istream != null) {                    try {                        istream.close();                    } catch (Throwable t) {                        ;                    }                    istream = null;                }            } finally {                entry = null;                if (jar != null) {                    try {                        jar.close();                    } catch (Throwable t) {                        ;                    }                    jar = null;                }            }        }        //这个是用来存放已经部暑好的文件        DeployedApplication deployedApp = new DeployedApplication(contextPath);                // Deploy the application in this WAR file        if(log.isInfoEnabled())             log.info(sm.getString("hostConfig.deployJar", file));        try {            Context context = null;            if (deployXML && xml.exists()) {                synchronized (digester) {                    try {                        context = (Context) digester.parse(xml);                        if (context == null) {                            log.error(sm.getString("hostConfig.deployDescriptor.error",                                    file));                            return;                        }                    } finally {                        digester.reset();                    }                }                context.setConfigFile(xml.getAbsolutePath());                deployedApp.redeployResources.put                    (xml.getAbsolutePath(), new Long(xml.lastModified()));            } else {                context = (Context) Class.forName(contextClass).newInstance();            }            // Populate redeploy resources with the WAR file            deployedApp.redeployResources.put                (war.getAbsolutePath(), new Long(war.lastModified()));            if (context instanceof Lifecycle) {                Class clazz = Class.forName(host.getConfigClass());                LifecycleListener listener =                    (LifecycleListener) clazz.newInstance();                ((Lifecycle) context).addLifecycleListener(listener);            }            context.setPath(contextPath);            context.setDocBase(file);            //以下这一步跟进去,StandardContext的启动            host.addChild(context);            // If we're unpacking WARs, the docBase will be mutated after            // starting the context            if (unpackWARs && (context.getDocBase() != null)) {                String name = null;                String path = context.getPath();                if (path.equals("")) {                    name = "ROOT";                } else {                    if (path.startsWith("/")) {                        name = path.substring(1);                    } else {                        name = path;                    }                }                name = name.replace('/', '#');                File docBase = new File(name);                if (!docBase.isAbsolute()) {                    docBase = new File(appBase(), name);                } //将部暑完的工程存放进该map中                deployedApp.redeployResources.put(docBase.getAbsolutePath(),                        new Long(docBase.lastModified()));                addWatchedResources(deployedApp, docBase.getAbsolutePath(), context);            } else {                addWatchedResources(deployedApp, null, context);            }        } catch (Throwable t) {            log.error(sm.getString("hostConfig.deployJar.error", file), t);        }                deployed.put(contextPath, deployedApp);    }

? //以下这一步跟进去,StandardContext的启动

            host.addChild(context);
private void addChildInternal(Container child) {        if( log.isDebugEnabled() )            log.debug("Add child " + child + " " + this);        synchronized(children) {            if (children.get(child.getName()) != null)                throw new IllegalArgumentException("addChild:  Child name '" +                                                   child.getName() +                                                   "' is not unique");            child.setParent(this);  // May throw IAE            children.put(child.getName(), child);            // Start child            if (started && startChildren && (child instanceof Lifecycle)) {                boolean success = false;                try {    //StandardContext的启动                    ((Lifecycle) child).start();                    success = true;                } catch (LifecycleException e) {                    log.error("ContainerBase.addChild: start: ", e);                    throw new IllegalStateException                        ("ContainerBase.addChild: start: " + e);                } finally {                    if (!success) {                        children.remove(child.getName());                    }                }            }            fireContainerEvent(ADD_CHILD_EVENT, child);        }    }

?StandardContext#start//由于里面的方法过长,就对里面的个别调用进行详解

 public synchronized void start() throws LifecycleException {     if( !initialized ) {             try {               //war文件解压缩成工程就是在这步执行                init();            } catch( Exception ex ) {                throw new LifecycleException("Error initializaing ", ex);            }        }}

?以上是对环境部暑启动的简单调试过程,没能全部理解清楚,,会根据后面的调试补全

主要是做了把工程文件存放在DeployedApplication这个类里的??deployedApp.redeployResources.put(docBase.getAbsolutePath(),

?? ? ? ? ? ? ? ? ? ? ? ?new Long(docBase.lastModified()));以备访问调用?

读书人网 >软件架构设计

热点推荐