Tomcat源码学习(18)-第五章-容器
在tomcat里有四种容器,它们都需要实现org.apache.catalina.Container接口
容器的使用如下:
HttpConnector connector = new HttpConnector();
SimpleContainer container = new SimpleContainer();
connector.setContainer(container);
四种容器:
Engine. Represents the entire Catalina servlet engine表示整个Catalina 的Servlet引擎
Host. Represents a virtual host with a number of contexts:虚拟host
Context. Represents a web application. A context contains one or more wrappers.表示一个应用请求
Wrapper. Represents an individual servlet:表示一个单独的Servlet
这四种容器都在org.apache.catalina.core中有实现分别为StandardEngine, StandardHost, StandardContext, and StandardWrapper。
一个容器可以有另个或者多个子层次的容器。例如:一个context可以有一个活多个wrappers而且一个host可以一个活多个的context。但是wrappers处于最底层
不能再包含子容器。使用container接口中定义的addChild方法可以给一个容器添加容器。
removeChild方法删除容器
public Container findChild(String name)查找容器
public Container[]findChildren()查找所有子容器
一个容器还可以包含一系列支持性的部件如:Loader、logger、Manager、Realm和Resources。Container接口提供了这些部件的set和get方法。包括getLoader and setLoader, getLogger and setLogger, getManager and setManager, getRealm and setRealm, and getResources and setResources.
用户可以通过定制server.xml文件来定制Container
A container can have one pipeline. When a container's invoke method is called, the container passes processing to its pipeline and the pipeline invokes the first valve in it, which will then invoke the next valve, and so on, until there is no more valve in the pipeline.
容器的invoke方法如下
public void invoke(Request request, Response response) throws IOException, ServletException
{ pipeline.invoke(request, response); }
pipeline是Pipeline接口的实例。
ValveContext是pipeline的内部类使用它可以一个一个的invoke容器。
tomcat4中的StandardPipelineValveContext 的实现:
protected class StandardPipelineValveContext implements ValveContext {
protected int stage = 0;
public String getInfo() {
return info;
}
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
(sm.getString("standardPipeline.noValve"));
}
}
}
tomcat5中的StandardValveContext 替换了原来的StandardPipelineValveContext
import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.catalina.Request;
import org.apache.catalina.Response;
import org.apache.catalina.Valve;
import org.apache.catalina.ValveContext;
import org.apache.catalina.util.StringManager;
public final class StandardValveContext implements ValveContext {
protected static StringManager sm =
StringManager.getManager(Constants.Package);
protected String info =
"org.apache.catalina.core.StandardValveContext/1.0";
protected int stage = 0;
protected Valve basic = null;
protected Valve valves[] = null;
public String getInfo() {
return info;
}
public final 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
(sm.getString("standardPipeline.noValve"));
}
}
void set(Valve basic, Valve valves[]) {
stage = 0;
this.basic = basic;
this.valves = valves;
}
}
Pipeline Interface定义如下:
package org.apache.catalina;
import java.io.IOException;
import javax.servlet.ServletException;
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);
}