StandardWrapper
wrapper的定义
wrapper原本在java中指的是一个包装类,在tomcat中是一个接口,StandardwrapperWrapper 代表一个 Servlet,它负责管理一个 Servlet,包括的 Servlet 的装载、初始化、执行以及资源回收。它的父容器一般是Context,Wrapper 是最底层的容器,它没有子容器了,所以调用它的 addChild 将会抛illegalargumentexception。Wrapper 的实现类是 StandardWrapper,StandardWrapper 还实现了拥有一个 Servlet 初始化信息的 ServletConfig,由此看出 StandardWrapper 将直接和 Servlet 的各种信息打交道。
在StandardContext启动时,读取web.xml配置文件,配置Context之后,紧接着启动Context的一些附属组件,除此以外还加载了那些标记为”load on start”的那些wrapper。
源码分析
public synchronized void load() throws ServletException {
instance = loadServlet();/*创建servelt实例*/
if (!instanceInitialized) {
initServlet(instance);/*对servlet进行初始化*/
}
if (isJspServlet) {
StringBuilder oname = new StringBuilder(getDomain());
oname.append(":type=JspMonitor");
oname.append(getWebModuleKeyProperties());
oname.append(",name=");
oname.append(getName());
oname.append(getJ2EEKeyProperties());
try {
jspMonitorON = new ObjectName(oname.toString());
Registry.getRegistry(null, null)
.registerComponent(instance, jspMonitorON, null);
} catch( Exception ex ) {
log.info("Error registering JSP monitoring with jmx " +
instance);
}
}
}
先用loadServlet()这个方法进行初始化,如果没有初始化,在用initServlet方法进行初始化,事实上,在loadServlet方法里也调用了initServlet这个方法。
然后看看它是怎么初始化Servlet的:
private synchronized void initServlet(Servlet servlet)
throws ServletException {
if (instanceInitialized && !singleThreadModel) return;
// Call the initialization method of this servlet
try {
if( Globals.IS_SECURITY_ENABLED) {
boolean success = false;
try {
Object[] args = new Object[] { facade };
SecurityUtil.doAsPrivilege("init",
servlet,
classType,
args);
success = true;
} finally {
if (!success) {
// destroy() will not be called, thus clear the reference now
SecurityUtil.remove(servlet);
}
}
} else {
servlet.init(facade);
}
instanceInitialized = true;
} catch (UnavailableException f) {
unavailable(f);
throw f;
} catch (ServletException f) {
// If the servlet wanted to be unavailable it would have
// said so, so do not call unavailable(null).
throw f;
} catch (Throwable f) {
ExceptionUtils.handleThrowable(f);
getServletContext().log("StandardWrapper.Throwable", f );
// If the servlet wanted to be unavailable it would have
// said so, so do not call unavailable(null).
throw new ServletException
(sm.getString("standardWrapper.initException", getName()), f);
}
}
可以看到,他调用了securityUtil这个类里面的方法,这里不展开讨论。
至此,web应用加载的分析告一段落。