Host和Engine
如果你想在同一个Tomcat部署多个Context容器。需要使用Host容器。
Context容器的父容器通常是Host容器,也可能是其他实现。或者如果不必要,就可以不使用父容器。(但是总会使用一个Host)
Engine容器表示Catalina的整个servlet引擎。如果使用了Engine容器,它总是处于容器最顶层。添加的通常是host或者context。
Host接口
比较重要的是map(),返回一个处理HTTP请求的Context容器。
StandardHost
继承自ContainerBase类。实现Host和Deployer接口。
与StandardContext和StandardWrapper类似,构造函数将一个基础阀实例添加到管道对象中。
基础阀StandardHostValve类。
当调用start()会添加ErrorReportValve阀与ErrorDispatcherValve阀。
每引入一个Http请求,都会调用Host实例的invoke方法。由于StandardHost没有该方法,因此调用父类ContainerBase类的invoke()->调基础阀StandardHostValve的invoke()->调StandardHost的map(),来处理请求。
StandardHostMapper类。
ContainerBase类,会调用addDefaultMapper(),创建一个默认映射器。
map(),只是调用了Host实例的map()。
为什么必须有一个Host容器
若一个Context实例,使用ContextConfig对象进行设置。就必须使用一个Host对象。
因为,使用ContextConfig对象,需要知道web.xml文件的位置。在其applicationConfig()方法中它会试图打开web.xml文件。
URL url = servletContext.getResource(Constants.ApplicationWebXml);
Constants.ApplicationWebXml 的值为"/WEB-INF/web.xml" 。servletContext是applicationContext类型。
public URL getResource(String path){
DirContext resources = context.getResource();
if(resource != null){
String fullPath = context.getName()+path;
String hostName = context.getParent().getName(); //host不能为空
}
}
Engine接口
Engine容器也就是servlet引擎。部署Tomcat时,支持多个虚拟机的话,需要使用Engine容器。
在Engine容器中,可以设置一个默认的Host或者Context容器。
StandardEngine类
作为顶层容器,子容器只能是Host容器,所以若给它设置一个非Host容器,抛出异常。
不能有父容器,Add会抛异常
StandardEngineValve类
是基础阀。invoke()。验证request和response类型。得到Host实例,处理该请求。invoke方法通过调Engine的map()获取host对象。调用其invoke方法。