在上一篇的文章中看了StandardService的实现。。。这里可以将它要做的事情总结如下:
(1)管理其拥有的container对象,以及其拥有的connector对象,同时service只能有一个container对象,可以拥有多个connector对象。。。
(2)StandardService对象同时还要处理request的map问题,它有maplistener和mapper,maplistener用于监听container对象,从而增加mapper里面的信息。。。
上面说service只能有一个Container对象,这个container对象其实一般就是Engine对象,而Engine对象一般都是使用StandardEngine的。。。但是在具体的分析StandardEngine之前呢,先来看看Valve的设计。。。
在以前分析Container的时候提到过,每个container对象都有一个pipeline对象用于处理请求,而pipeline其实则是一个valve的链表,它是用valve对象来具体的处理请求的。。。
这里就先来看看valve接口的设计吧:
//value对象是与container相关联的处理请求的组件,一系列的value组成了pipeline
public interface Valve {
public Valve getNext(); //返回pipeline的下一个value对象,在pipeline上面,valve对象组成了一个链表
public void setNext(Valve valve); //设置下一个value对象
//执行一些周期的工作
public void backgroundProcess();
//处理request与response
public void invoke(Request request, Response response)
throws IOException, ServletException;
//处理comet事件
public void event(Request request, Response response, CometEvent event)
throws IOException, ServletException;
//是否支持异步
public boolean isAsyncSupported();
}
接口的设计应该蛮简的,从getNext和setNext两个方法的名字就知道valve对象构成了一个链表。。。
这里还有一个invoke方法用于处理具体的http请求。。。。当然还有个event方法用于响应comet事件。。。。
好啦,大概知道valve是干嘛的了,接下来就来看看Engine吧,先来看看它的接口的定义吧:
public interface Engine extends Container {
public String getDefaultHost(); //返回当前host用的默认host名字
public void setDefaultHost(String defaultHost); //设置host名字
public String getJvmRoute(); //
public void setJvmRoute(String jvmRouteId); //jvm的routeid
public Service getService(); //返回当前engine关联的service
public void setService(Service service); //设置当前关联的service
}
这里可以看到继承了Container接口。。。方法还是挺少的。。。这里DefaultHost是用于配置当前engine对象默认使用的host对象。。。因为在engine中可以定义多个host,通过名字来指定一个默认的host。。。
好啦,接下来就来看看StandardEngine的实现吧,它首先继承了ContainerBase,那么可以进行container以及pipeline的管理。。然后当然还有实现engine接口了。。。
来看看它的构造方法吧:
public StandardEngine() {
super();
pipeline.setBasic(new StandardEngineValve()); //这里会设置pipeline的basic
/* Set the jmvRoute using the system property jvmRoute */
try {
setJvmRoute(System.getProperty("jvmRoute")); //这个是集群用的吧
} catch(Exception ex) {
log.warn(sm.getString("standardEngine.jvmRouteFail"));
}
// By default, the engine will hold the reloading thread
backgroundProcessorDelay = 10; //后台处理延迟10
}
这里主要要做的事情就是在pipeline上面添加一个basic的valve吧。。。然后jvmroute用于集群的,这个就暂时不看了。。
再来看看它的一些属性的定义吧:
private String defaultHost = null; //当前engine对象用的默认的host的名字
private Service service = null; //所属的service对象
private String jvmRouteId;
这个也没啥意思吧,具体的干嘛用的注释也说了。。。。
另外来看看这里的addChild方法:
//这里只能加入host
public void addChild(Container child) { //添加child
if (!(child instanceof Host))
throw new IllegalArgumentException
(sm.getString("standardEngine.notHost"));
super.addChild(child);
}
嗯,engine对象的child只能是host对象。。。
另外再来看看setParent方法:
//设置父container,engine对象是最上层的container对象了,所以它没有添加parent的方法
public void setParent(Container container) {
throw new IllegalArgumentException
(sm.getString("standardEngine.notParent"));
}
可以知道engine对象是最顶层的container对象。。。。。
这里再来看看在catalina的createStartDigester方法中的一段代码。。这个是用于通过解析server.xml文件来创建server对象的部分。。。
digester.addRule("Server/Service/Engine",
new SetParentClassLoaderRule(parentClassLoader)); //如果有发现engine,那么设置container(Engine对象)的parentClassloader,shareloader
通过这段代码是想提醒一下,engine对象在创建的时候会将parentClassLoader设置为sharLoader。。。
好啦,最后我们在StandardEngine的构造函数中看到设置了pipeline对象的basic的valve为StandardEngineValve对象。。。那么就来看看它的invoke方法就好啦吧:
@Override
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// Select the Host to be used for this Request
Host host = request.getHost(); //获取这个请求所map的host对象
if (host == null) { //若果没有的话,那就可以说出错了
response.sendError
(HttpServletResponse.SC_BAD_REQUEST,
sm.getString("standardEngine.noHost",
request.getServerName()));
return;
}
if (request.isAsyncSupported()) { //根据host的pipeline对象来设置当前是否支持异步
request.setAsyncSupported(host.getPipeline().isAsyncSupported());
}
// Ask this Host to process this request
host.getPipeline().getFirst().invoke(request, response); //调用host对象的pipeline来处理这个请求
}
感觉这里没做太多的事情吧,主要是获取当前request的所map到的host对象,然后调用host对象的pipeline来处理就好了。。。
那么到这里StandardEngine就差不多吧,感觉要做的事情不多。。