tomcat是怎样找到servlet的?
(1)首先我们来看一下tomcat是怎样把路径加入到mapper中的
①tomcat在启动的时候会注册Host,这个时候mapper会把Host加入到MappedHost中 Mpper#registerHost()
/**
* Register host.
*/
private void registerHost(Host host) {
String[] aliases = host.findAliases();
//添加Host到Mapper中
mapper.addHost(host.getName(), aliases, host);
//这个方法主要把context添加到host中
for (Container container : host.findChildren()) {
if (container.getState().isAvailable()) {
//这个方法主要是把Contex添加到
registerContext((Context) container);
}
}
if(log.isDebugEnabled()) {
log.debug(sm.getString("mapperListener.registerHost",
host.getName(), domain, service));
}
}
这个方法其实是把host加入到其中的一个数组中去,mapper中有一个MappedHost[]
volatile MappedHost[] hosts = new MappedHost[0];
/**
* Add a new host to the mapper.
*
* @param name Virtual host name
* @param aliases Alias names for the virtual host
* @param host Host object
*/
public synchronized void addHost(String name, String[] aliases,
Host host) {
//修改通配符名字,去掉以*.开头的host名字
name = renameWildcardHost(name);
//创建一个新的数组装这个host
MappedHost[] newHosts = new MappedHost[hosts.length + 1];
//封装这个新的host
MappedHost newHost = new MappedHost(name, host);
//将host添加至 MappedHost[] hosts中,如果是重名的话会返回失败,如果是可以插入的话则按照顺序插入
if (insertMap(hosts, newHosts, newHost)) {
hosts = newHosts;
//如果新的主机的名字是localhost的话,把新的主机赋值给默认主机
if (newHost.name.equals(defaultHostName)) {
defaultHost = newHost;
}
if (log.isDebugEnabled()) {
log.debug(sm.getString("mapper.addHost.success", name));
}
} else {
//如果是重复的话,则把重复的主机赋值给新的主机
MappedHost duplicate = hosts[find(hosts, name)];
if (duplicate.object == host) {
// The host is already registered in the mapper.
// E.g. it might have been added by addContextVersion()
if (log.isDebugEnabled()) {
log.debug(sm.getString("mapper.addHost.sameHost", name));
}
newHost = duplicate;
} else {
log.error(sm.getString("mapper.duplicateHost", name,
duplicate.getRealHostName()));
// Do not add aliases, as removeHost(hostName) won't be able to
// remove them
return;
}
}
//如果存在别名的话,则对主机进行别名设置
List<MappedHost> newAliases = new ArrayList<>(aliases.length);
for (String alias : aliases) {
alias = renameWildcardHost(alias);
MappedHost newAlias = new MappedHost(alias, newHost);
if (addHostAliasImpl(newAlias)) {
newAliases.add(newAlias);
}
}
newHost.addAliases(newAliases);
}
上面这个方法主要是把host添加到MappedHost[]
② registerContext((Context) container);
将context添加到host中
/**
* Register context.
*/
private void registerContext(Context context) {
String contextPath = context.getPath();
if ("/".equals(contextPath)) {
contextPath = "";
}
Host host = (Host)context.getParent();
WebResourceRoot resources = context.getResources();
//设置欢迎页面数组
String[] welcomeFiles = context.findWelcomeFiles();
//创建一个wrapper数组
List<WrapperMappingInfo> wrappers = new ArrayList<>();
//这个方法主要是把wrapper添加到context
for (Container container : context.findChildren()) {
//这个方法主要是把wrapper包装成WrapperMappingInfo,然后装入到List<WrapperMappingInfo>中
prepareWrapperMappingInfo(context, (Wrapper) container, wrappers);
if