新增Web应用时创建注入ContextConfig对象;
//org.apache.catalina.startup.Tomcat#addWebapp
public Context addWebapp(Host host, String url, String name, String path) {
silence(host, url);
//1. 创建standardContext
Context ctx = new StandardContext();
ctx.setName(name);
ctx.setPath(url);
ctx.setDocBase(path);
ctx.addLifecycleListener(new DefaultWebXmlListener());
//创建contextConfig
ContextConfig ctxCfg = new ContextConfig();
ctx.addLifecycleListener(ctxCfg);
// prevent it from looking ( if it finds one - it'll have dup error )
ctxCfg.setDefaultWebXml(noDefaultWebXmlPath());
if (host == null) {
getHost().addChild(ctx);
} else {
host.addChild(ctx);
}
return ctx;
}
ContextConfig 记录servlet配置信息,
当StandardContext.init()时, ContextConfig.init()被调用, contextconfig解析配置信息的功能由类Digester来实现.
在Tomcat中Servlet的创建由StandardWrapper来实现.
//org.apache.catalina.core.StandardWrapper
//存储单例的Servlet
protected Stack<Servlet> instancePool = null;
//存储非单例的Servlet, 注意此处的volatile关键字
protected volatile Servlet instance = null;
public boolean isSingleThreadModel() {
if (singleThreadModel || instance != null) {
return singleThreadModel;
}
try {
Servlet s = allocate();
deallocate(s);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
}
return (singleThreadModel);
}