一,容器已经启动到部暑文件(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()));以备访问调用