• 容器的注册


    MapperListener.startInternal
    
    public void startInternal() throws LifecycleException {
    
            setState(LifecycleState.STARTING);
    
            Engine engine = service.getContainer();
            if (engine == null) {
                return;
            }
    
    //寻找默认的host,给engine设置默认的host
            findDefaultHost();
    
    //给engine和子容器添加MapperListener
            addListeners(engine);
    
    //获取所有的host
            Container[] conHosts = engine.findChildren();
            for (Container conHost : conHosts) {
                Host host = (Host) conHost;
                if (!LifecycleState.NEW.equals(host.getState())) {
                    // Registering the host will register the context and wrappers
                    registerHost(host);
                }
            }
        }
    
    
    MapperListener.registerHost
    
    private void registerHost(Host host) {
    
    //获取别名
            String[] aliases = host.findAliases();
    //添加host
            mapper.addHost(host.getName(), aliases, host);
    //注册context
            for (Container container : host.findChildren()) {
                if (container.getState().isAvailable()) {
                    registerContext((Context) container);
                }
            }
            if(log.isDebugEnabled()) {
                log.debug(sm.getString("mapperListener.registerHost",
                        host.getName(), domain, service));
            }
        }
    
    Mapper.addHost
    
    public synchronized void addHost(String name, String[] aliases,
                                         Host host) {
    //重命名主机通配符,比如*.apache.org,会把开头这种通配符*去掉,变成.apache.org
            name = renameWildcardHost(name);
            MappedHost[] newHosts = new MappedHost[hosts.length + 1];
            MappedHost newHost = new MappedHost(name, host);
    //插入到mappedHosts集合中,会用过名字进行排序
            if (insertMap(hosts, newHosts, newHost)) {
                hosts = newHosts;
    //设置默认的host
                if (newHost.name.equals(defaultHostName)) {
                    defaultHost = newHost;
                }
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("mapper.addHost.success", name));
                }
    //如果插入失败
            } else {
    //从host集合中查找到这个同名的MappedHost
                MappedHost duplicate = hosts[find(hosts, name)];
    //如果这个MappedHost中的host和当前的host是同一个
                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));
                    }
    //将这个已经存在的host复制给newHost
                    newHost = duplicate;
                } else {
    //如果存在同名的host并且和注册的host不一样,那么直接返回,不对别名进行注册
                    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) {
    //重命名别名,和上面重命名name是一样的操作
                alias = renameWildcardHost(alias);
                MappedHost newAlias = new MappedHost(alias, newHost);//持有真实的MappedHost
                if (addHostAliasImpl(newAlias)) {
                    newAliases.add(newAlias);
                }
            }
            newHost.addAliases(newAliases);
        }
    
    Mapper.insertMap(hosts, newHosts, newHost)
    
    private static final <T> boolean insertMap
            (MapElement<T>[] oldMap, MapElement<T>[] newMap, MapElement<T> newElement) {
           //寻找可以插入的位置,按照name进行从小到大排序 
    int pos = find(oldMap, newElement.name);
    //如果新host的name和已经存在的host的名字一样,那么表示已经存在了,插入失败
            if ((pos != -1) && (newElement.name.equals(oldMap[pos].name))) {
                return false;
            }
    //将旧的host集合copy的到新的host集合中
            System.arraycopy(oldMap, 0, newMap, 0, pos + 1);
            newMap[pos + 1] = newElement;
    //将旧得剩余的hostcopy到新数组中
            System.arraycopy
                (oldMap, pos + 1, newMap, pos + 2, oldMap.length - pos - 1);
            return true;
        }
    
    Mapper.find()
    
    private static final <T> int find(MapElement<T>[] map, String name) {
    
            int a = 0;
            int b = map.length - 1;
    
            // Special cases: -1 and 0 如果旧的hosts集合没有任何东西,直接返回-1,表示可以直接从零位置插入
            if (b == -1) {
                return -1;
            }
    
    //如果新的host比第一个位置的host小,那么直接返回-1,从零位置插入
            if (name.compareTo(map[0].name) < 0) {
                return -1;
            }
    //如果host结合中存在一个元素,并且这个元素不比零位置的host小,那么返回零,插入到1位置
            if (b == 0) {
                return 0;
            }
    
            int i = 0;
    //二分法查找可以插入的位置
            while (true) {
                i = (b + a) / 2;
                int result = name.compareTo(map[i].name);
                if (result > 0) {
                    a = i;
                } else if (result == 0) {
                    return i;
                } else {
                    b = i;
                }
                if ((b - a) == 1) {
                    int result2 = name.compareTo(map[b].name);
                    if (result2 < 0) {
                        return a;
                    } else {
                        return b;
                    }
                }
            }
    
        }
    
    Mapper.addHostAliasImpl
    //这段代码和addHost上部分
    private synchronized boolean addHostAliasImpl(MappedHost newAlias) {
            MappedHost[] newHosts = new MappedHost[hosts.length + 1];
            if (insertMap(hosts, newHosts, newAlias)) {
                hosts = newHosts;
                if (newAlias.name.equals(defaultHostName)) {
                    defaultHost = newAlias;
                }
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("mapper.addHostAlias.success",
                            newAlias.name, newAlias.getRealHostName()));
                }
                return true;
            } else {
                MappedHost duplicate = hosts[find(hosts, newAlias.name)];
                if (duplicate.getRealHost() == newAlias.getRealHost()) {
                    // A duplicate Alias for the same Host.
                    // A harmless redundancy. E.g.
                    // <Host name="localhost"><Alias>localhost</Alias></Host>
                    if (log.isDebugEnabled()) {
                        log.debug(sm.getString("mapper.addHostAlias.sameHost",
                                newAlias.name, newAlias.getRealHostName()));
                    }
                    return false;
                }
                log.error(sm.getString("mapper.duplicateHostAlias", newAlias.name,
                        newAlias.getRealHostName(), duplicate.getRealHostName()));
                return false;
            }
        }
    
    Mapper.registerContext
    
    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();
            List<WrapperMappingInfo> wrappers = new ArrayList<>();
    
            for (Container container : context.findChildren()) {
                prepareWrapperMappingInfo(context, (Wrapper) container, wrappers);
    
                if(log.isDebugEnabled()) {
                    log.debug(sm.getString("mapperListener.registerWrapper",
                            container.getName(), contextPath, service));
                }
            }
    //添加context版本
            mapper.addContextVersion(host.getName(), host, contextPath,
                    context.getWebappVersion(), context, welcomeFiles, resources,
                    wrappers);
    
            if(log.isDebugEnabled()) {
                log.debug(sm.getString("mapperListener.registerContext",
                        contextPath, service));
            }
        }
    
    MapperListener.prepareWrapperMappingInfo
    
    private void prepareWrapperMappingInfo(Context context, Wrapper wrapper,
                List<WrapperMappingInfo> wrappers) {
            String wrapperName = wrapper.getName();
            boolean resourceOnly = context.isResourceOnlyServlet(wrapperName);
            String[] mappings = wrapper.findMappings();
    //以映射为维度,添加每个wrapper
            for (String mapping : mappings) {
                boolean jspWildCard = (wrapperName.equals("jsp")
                                       && mapping.endsWith("/*"));
                wrappers.add(new WrapperMappingInfo(mapping, wrapper, jspWildCard,
                        resourceOnly));
            }
        }
    
    Mapper.addContextVersion
    
    public void addContextVersion(String hostName, Host host, String path,
                String version, Context context, String[] welcomeResources,
                WebResourceRoot resources, Collection<WrapperMappingInfo> wrappers) {
    
            hostName = renameWildcardHost(hostName);
    //精确查找MappedHost,如果不存在,那么就加入
            MappedHost mappedHost  = exactFind(hosts, hostName);
            if (mappedHost == null) {
                addHost(hostName, new String[0], host);
                mappedHost = exactFind(hosts, hostName);
                if (mappedHost == null) {
                    log.error("No host found: " + hostName);
                    return;
                }
            }
    //是否是别名,如果是别名,那么对应的正统host和当前的对象不一致,直接返回
            if (mappedHost.isAlias()) {
                log.error("No host found: " + hostName);
                return;
            }
    //计算路径中/的个数
            int slashCount = slashCount(path);
            synchronized (mappedHost) {
    //创建当前context版本
                ContextVersion newContextVersion = new ContextVersion(version,
                        path, slashCount, context, resources, welcomeResources);
                if (wrappers != null) {
    //将wrappers进行分类,通配符wrapper,扩展型,精确型wrapper集合
                    addWrappers(newContextVersion, wrappers);
                }
    
                ContextList contextList = mappedHost.contextList;
                MappedContext mappedContext = exactFind(contextList.contexts, path);
                if (mappedContext == null) {
                    mappedContext = new MappedContext(path, newContextVersion);
    //添加mappedContext到 ContextList中
                    ContextList newContextList = contextList.addContext(
                            mappedContext, slashCount);
                    if (newContextList != null) {
    //返回了新的集合后,需要替换掉MappedHost与别名中的contextList
                        updateContextList(mappedHost, newContextList);
    //将context对象和对应版本添加到map中
                        contextObjectToContextVersionMap.put(context, newContextVersion);
                    }
                } else {
    //获取版本版本
                    ContextVersion[] contextVersions = mappedContext.versions;
                    ContextVersion[] newContextVersions = new ContextVersion[contextVersions.length + 1];
    //插入版本,如果对应的版本已经存在,那么直接替换掉。
                    if (insertMap(contextVersions, newContextVersions,
                            newContextVersion)) {
                        mappedContext.versions = newContextVersions;
                        contextObjectToContextVersionMap.put(context, newContextVersion);
                    } else {
                        // Re-registration after Context.reload()
                        // Replace ContextVersion with the new one
                        int pos = find(contextVersions, version);
                        if (pos >= 0 && contextVersions[pos].name.equals(version)) {
                            contextVersions[pos] = newContextVersion;
                            contextObjectToContextVersionMap.put(context, newContextVersion);
                        }
                    }
                }
            }
    
        }
    
    Mapper.addWrapper
    
    protected void addWrapper(ContextVersion context, String path,
                Wrapper wrapper, boolean jspWildCard, boolean resourceOnly) {
    
            synchronized (context) {
                if (path.endsWith("/*")) {
                    // Wildcard wrapper
                    String name = path.substring(0, path.length() - 2);
                    MappedWrapper newWrapper = new MappedWrapper(name, wrapper,
                            jspWildCard, resourceOnly);
    //通配符wrapper集合
                    MappedWrapper[] oldWrappers = context.wildcardWrappers;
                    MappedWrapper[] newWrappers = new MappedWrapper[oldWrappers.length + 1];
                    if (insertMap(oldWrappers, newWrappers, newWrapper)) {
                        context.wildcardWrappers = newWrappers;
                        int slashCount = slashCount(newWrapper.name);
                        if (slashCount > context.nesting) {
                            context.nesting = slashCount;
                        }
                    }
                } else if (path.startsWith("*.")) {
                    // Extension wrapper
                    String name = path.substring(2);
                    MappedWrapper newWrapper = new MappedWrapper(name, wrapper,
                            jspWildCard, resourceOnly);
    //扩展名wrapper
                    MappedWrapper[] oldWrappers = context.extensionWrappers;
                    MappedWrapper[] newWrappers =
                        new MappedWrapper[oldWrappers.length + 1];
                    if (insertMap(oldWrappers, newWrappers, newWrapper)) {
                        context.extensionWrappers = newWrappers;
                    }
                } else if (path.equals("/")) {
                    // Default wrapper
                    MappedWrapper newWrapper = new MappedWrapper("", wrapper,
                            jspWildCard, resourceOnly);
                    context.defaultWrapper = newWrapper;
                } else {
                    // Exact wrapper
                    final String name;
                    if (path.length() == 0) {
                        // Special case for the Context Root mapping which is
                        // treated as an exact match
                        name = "/";
                    } else {
                        name = path;
                    }
                    MappedWrapper newWrapper = new MappedWrapper(name, wrapper,
                            jspWildCard, resourceOnly);
    //精确匹配wrapper
                    MappedWrapper[] oldWrappers = context.exactWrappers;
                    MappedWrapper[] newWrappers = new MappedWrapper[oldWrappers.length + 1];
                    if (insertMap(oldWrappers, newWrappers, newWrapper)) {
                        context.exactWrappers = newWrappers;
                    }
                }
            }
        }
  • 相关阅读:
    centos安装vsftp
    php利用soap实现webservice 和利用soap调用其他语言的webservice
    php连接redis数据库 操作redis任务队列
    shopnc编译安装IM服务器node.js
    centos6.5 64位 yum install nginx的默认安装路径
    安装nfs服务器
    php扩展redis,编译安装redis服务
    x86_64编译JPEG遇到Invalid configuration `x86_64-unknown-linux-gnu'
    shopnc nginx优化配置文件
    nginx支持flv MP4 扩展nginx_mod_h264_streaming,nginx-rtmp-module-master,yamdi
  • 原文地址:https://www.cnblogs.com/honger/p/10363075.html
Copyright © 2020-2023  润新知