在地址栏输入的 URI , Tomcat 是如何找到对应的 Servlet 或 JSP (Jsp 就是一个 Servlet) 呢 ?
其实在启动 Tomcat 组件 MapperListener 的时候, 就将对应的映射关系放入了一个 Mapper 中, 它有这几个作用
- 映射关系存储:存储所有的 Host,Context 及 Wrapper 的对应关系;
- 映射关系初始化及变更:当新增一个组件或者移除一个组件时,Mapper 如何维护 URI 到 Wrapper 的映射关系;
- 映射关系使用 :根据 URI,映射到具体的 Host,Context 和 wrapper
Mapper
public final class Mapper {
// 存储所有的 Host
volatile MappedHost[] hosts = new MappedHost[0];
...
protected abstract static class MapElement<T> {
public final String name;
public final T object;
public MapElement(String name, T object) {
this.name = name;
this.object = object;
}
}
// 这个里面存储的是 MappedContext 数组
protected static final class ContextList {
public final MappedContext[] contexts;
...
}
// 带版本号的 Context , 在 URI 请求参数中可以带版本号
// 一个 MappedContext 对应一个 ContextVersion (通过 path 对应)
protected static final class ContextVersion extends MapElement<Context> {
// context 的匹配路径
public final String path;
public final int slashCount;
public final WebResourceRoot resources;
// context 的欢迎页面
public String[] welcomeResources;
// 默认的 wrapper
public MappedWrapper defaultWrapper = null;
// 精确匹配路径的 wrapper
public MappedWrapper[] exactWrappers = new MappedWrapper[0];
// 通配符结尾的 wrapper
public MappedWrapper[] wildcardWrappers = new MappedWrapper[0];
// 扩展名匹配的 wrapper
public MappedWrapper[] extensionWrappers = new MappedWrapper[0];
public int nesting = 0;
// 这个context是否还可用,是否被暂停
private volatile boolean paused;
}
// URI 映射的主机
// 该 Host 下部署的所有 Web 应用, 存放的是 MappedContext 数组
protected static final class MappedHost extends MapElement<Host> {
public volatile ContextList contextList;
...
}
// URI 映射的 Context, 也就是一个 Web 应用