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