不过在tomcat中,如果要加载的servlet位于org.apache.catalina.下,那么classLoader就是
classLoader = this.getClass().getClassLoader(); //this 就是StandardWrapper
再下来就是loadClass,接着用Class的newInstance获得servlet;
下来就是检查该servlet是否允许载入(这步我看的不是很懂),看它是否实现了ContainerServlet接口。
ContainerServlet接口中有set/getWrapper方法,就是可以让servlet访问Catalina的内部功能。
下面就是调用 servlet.init(facade);这个facade是javax.servlet.ServletConfig的一个外观变量。
如果该StandardWrapper对象表示的是一个STM Servlet,将该实例添加到实例池中,因此,如果实例池如果为null,首先需要创建它。
// Register our newly initialized instance
singleThreadModel = servlet instanceof SingleThreadModel;
if (singleThreadModel) {
if (instancePool == null)
instancePool = new Stack();
}
fireContainerEvent("load", this);
}
最后返回servlet。
ServletConfig对象
上面servlet的init方法的参数实际上就是javax.servlet.ServletConfig接口的实例。问题出现了,这个接口的实例从哪来来呢?大家看看StandardWrapper的声明部分,就知道它本身就实现了ServletConfig接口。
但是在调用init方法是,StandardWrapper并不会直接把自己传过去而是使用了一个facade,为什么我主要是直接把StandardWrapper传过去,那么StandardWrapper里面的所有public方法不都暴露了么?
ServletConfig 接口有以下四个方法getServletContext,getServletName,getInitParameter,和getInitParameterNames。
1 getServletContext
public ServletContext getServletContext() {
if (parent == null)
return (null);
else if (!(parent instanceof Context))
return (null);
return (((Context) parent).getServletContext());
}
现在你知道不能单独部署一个包装器来表示一个 Servlet,包装器必须从属于一个上下文容器,这样才能使用 ServletConfig 对象使用getServletContext 方法获得一个 ServletContext 实例。
2 getServletName
获得servlet的名字,没有什么好说的
3 getInitParameter
获得指定的初始参数的值。StandardWrapper中的初始参数放在一个HashMap中:
private HashMap
具体的实现大家看代码,这块很简单。
4 getInitParameterNames
返回的是初始化参数的名字的集合,是一个枚举类。
StandardWrapperFacade类
类图如下:ServletConfig共有四个方法,facade类getServletName,getInitParameter,getInitParameterNames都是直接调用StandardWrapper,这些都比较简单,没有什么要说的。
不过getServletContext就有点复杂了:
public ServletContext getServletContext() {
ServletContext theContext = config.getServletContext();
if ((theContext != null) &&
(theContext instanceof ApplicationContext))
theContext = ((ApplicationContext) theContext).getFacade();
return (theContext);
}
看到了吧,先调用StandardWrapper获得Context,但是这里最后给外面返回的还是Facade。(真tm复杂)。
下面的章节我们会讲
StandardWrapperValve,FilterDef,ApplicationFilterConfig,ApplicationFilterChain