首先我们看看时序图(第一次画 可能在时序图规则上有些问题)
public class SimpleWrapper implements Wrapper, Pipeline {
// the servlet instance
private Servlet instance = null;
private String servletClass;
private Loader loader;
private String name;
private SimplePipeline pipeline = new SimplePipeline(this);
protected Container parent = null;
...
}
public class SimplePipeline implements Pipeline {
public SimplePipeline(Container container) {
setContainer(container);
}
// The basic Valve (if any) associated with this Pipeline.
protected Valve basic = null;
// The Container with which this Pipeline is associated.
protected Container container = null;
// the array of Valves
protected Valve valves[] = new Valve[0]; //所有的阀
}invokeNext是StandardPipelineValveContext类中的方法(StandardPipelineValveContext是管道的一个内部类,因此可以访问管道的所有成员)
public void invokeNext(Request request, Response response)
throws IOException, ServletException {
int subscript = stage;
stage = stage + 1;
// Invoke the requested Valve for the current request thread
if (subscript < valves.length) {
valves[subscript].invoke(request, response, this);
}
else if ((subscript == valves.length) && (basic != null)) {
basic.invoke(request, response, this);
}
else {
throw new ServletException("No valve");
}
}
} // end of inner classok?如水般流过。下面这行代码值得我们仔细看看
valves[subscript].invoke(request, response, this);
也可参阅拙作
<<说说struts2中拦截器的请求流程一(模拟大致流程)>>public class HeaderLoggerValve implements Valve, Contained {
protected Container container;
public void invoke(Request request, Response response, ValveContext valveContext)
throws IOException, ServletException {
// Pass this request on to the next valve in our pipeline
valveContext.invokeNext(request, response);
System.out.println("Header Logger Valve");
ServletRequest sreq = request.getRequest();
if (sreq instanceof HttpServletRequest) {
HttpServletRequest hreq = (HttpServletRequest) sreq;
Enumeration<?> headerNames = hreq.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement().toString();
String headerValue = hreq.getHeader(headerName);
System.out.println(headerName + ":" + headerValue);
}
}
else
System.out.println("Not an HTTP Request");
System.out.println("------------------------------------");
}
}public interface Pipeline {
public Valve getBasic();
public void setBasic(Valve valve);
public void addValve(Valve valve);
public Valve[] getValves();
public void invoke(Request request, Response response)
throws IOException, ServletException;
public void removeValve(Valve valve);
}Pipeline里面有个基础阀,是最后调用的,负责处理request对象鱼response对象。因而这里有getset方法public interface Valve {
public String getInfo();
public void invoke(Request request, Response response,ValveContext context) throws IOException, ServletException;
}public interface Contained {
public Container getContainer();
public void setContainer(Container container);
}类图如下:
public class SimpleLoader implements Loader {
public static final String WEB_ROOT =
System.getProperty("user.dir") + File.separator + "webroot";
ClassLoader classLoader = null;
Container container = null;
public SimpleLoader() {
try {
URL[] urls = new URL[1];
URLStreamHandler streamHandler = null;
File classPath = new File(WEB_ROOT);
String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString() ;
urls[0] = new URL(null, repository, streamHandler);
classLoader = new URLClassLoader(urls);
}
catch (IOException e) {
System.out.println(e.toString() );
}
}
}public void invoke(Request request, Response response, ValveContext valveContext)
throws IOException, ServletException {
SimpleWrapper wrapper = (SimpleWrapper) getContainer();
ServletRequest sreq = request.getRequest();
ServletResponse sres = response.getResponse();
Servlet servlet = null;
HttpServletRequest hreq = null;
if (sreq instanceof HttpServletRequest)
hreq = (HttpServletRequest) sreq;
HttpServletResponse hres = null;
if (sres instanceof HttpServletResponse)
hres = (HttpServletResponse) sres;
// Allocate a servlet instance to process this request
try {
servlet = wrapper.allocate();
if (hres!=null && hreq!=null) {
servlet.service(hreq, hres);
}
else {
servlet.service(sreq, sres);
}
}
catch (ServletException e) {
}
}public final class Bootstrap1 {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
/* call by using http://localhost:8080/ModernServlet,
but could be invoked by any name */
HttpConnector connector = new HttpConnector();
Wrapper wrapper = new SimpleWrapper();
wrapper.setServletClass("ModernServlet");
Loader loader = new SimpleLoader();
Valve valve1 = new HeaderLoggerValve();
Valve valve2 = new ClientIPLoggerValve();
wrapper.setLoader(loader);
((Pipeline) wrapper).addValve(valve1);
((Pipeline) wrapper).addValve(valve2);
connector.setContainer(wrapper);
try {
connector.initialize();
connector.start();
// make the application wait until we press a key.
System.in.read();
}
catch (Exception e) {
e.printStackTrace();
}
}
}how tomcat works 五 servlet容器 上
原文:http://blog.csdn.net/dlf123321/article/details/40110315