• context创建过程解析(三)之deployDirectories


    HostConfig.deployApps()
    //在监听到start事件类型,也就是StandardHost调用startInternal
    protected void deployApps() {
    
            File appBase = host.getAppBaseFile();
    //这个值是在触发before_start时间时生成的,默认是tomcat安装目录+engine名+host名
            File configBase = host.getConfigBaseFile();
    //获取host上配置的webapp下的所有文件,默认是webapps目录下的所有文件
            String[] filteredAppPaths = filterAppPaths(appBase.list());
            // Deploy XML descriptors from configBase  发布xml描述文件
            deployDescriptors(configBase, configBase.list());
            // Deploy WARs
            deployWARs(appBase, filteredAppPaths);
            // Deploy expanded folders
            deployDirectories(appBase, filteredAppPaths);
    
        }
    
    deployDirectories
    
    protected void deployDirectories(File appBase, String[] files) {
    
            if (files == null)
                return;
    
            ExecutorService es = host.getStartStopExecutor();
            List<Future<?>> results = new ArrayList<>();
    
            for (int i = 0; i < files.length; i++) {
    
                if (files[i].equalsIgnoreCase("META-INF"))
                    continue;
                if (files[i].equalsIgnoreCase("WEB-INF"))
                    continue;
                File dir = new File(appBase, files[i]);
                if (dir.isDirectory()) {
                    ContextName cn = new ContextName(files[i], false);
    
                    if (isServiced(cn.getName()) || deploymentExists(cn.getName()))
                        continue;
    
                    results.add(es.submit(new DeployDirectory(this, cn, dir)));
                }
            }
    
            for (Future<?> result : results) {
                try {
                    result.get();
                } catch (Exception e) {
                    log.error(sm.getString(
                            "hostConfig.deployDir.threaded.error"), e);
                }
            }
        }
    
    HostConfig.deployDirectory(cn, dir);
    
    protected void deployDirectory(ContextName cn, File dir) {
    
    
            long startTime = 0;
            // Deploy the application in this directory
            if( log.isInfoEnabled() ) {
                startTime = System.currentTimeMillis();
                log.info(sm.getString("hostConfig.deployDir",
                        dir.getAbsolutePath()));
            }
    
            Context context = null;
    //Constants.ApplicationContextXml == META-INF/context.xml
            File xml = new File(dir, Constants.ApplicationContextXml);
    //当允许copyxml的时候会使用到
            File xmlCopy =
                    new File(host.getConfigBaseFile(), cn.getBaseName() + ".xml");
    
    
            DeployedApplication deployedApp;
            boolean copyThisXml = isCopyXML();
            boolean deployThisXML = isDeployThisXML(dir, cn);
    
            try {
                if (deployThisXML && xml.exists()) {
                    synchronized (digesterLock) {
                        try {
                            context = (Context) digester.parse(xml);
                        } catch (Exception e) {
                            log.error(sm.getString(
                                    "hostConfig.deployDescriptor.error",
                                    xml), e);
                            context = new FailedContext();
                        } finally {
                            digester.reset();
                            if (context == null) {
                                context = new FailedContext();
                            }
                        }
                    }
    
    //这里有点疑问,为什么host配置的copyThisXml为false的时候才允许context进行覆盖?
                    if (copyThisXml == false && context instanceof StandardContext) {
                        // Host is using default value. Context may override it.
                        copyThisXml = ((StandardContext) context).getCopyXML();
                    }
    //当允许copy时,进行复制,并把配置文件设置为新的目录
                    if (copyThisXml) {
                        Files.copy(xml.toPath(), xmlCopy.toPath());
                        context.setConfigFile(xmlCopy.toURI().toURL());
                    } else {
                        context.setConfigFile(xml.toURI().toURL());
                    }
                } else if (!deployThisXML && xml.exists()) {//如果不允许发布这个配置文件并且对应的xml存在的话,构造失败context,why???即使存在context.xml也可以构造一个默认的context
                    // Block deployment as META-INF/context.xml may contain security
                    // configuration necessary for a secure deployment.
                    log.error(sm.getString("hostConfig.deployDescriptor.blocked",
                            cn.getPath(), xml, xmlCopy));
                    context = new FailedContext();
                } else {
                    context = (Context) Class.forName(contextClass).getConstructor().newInstance();
                }
    //下面的步骤和部署描述文件和部署war是一样的。不再赘述
                Class<?> clazz = Class.forName(host.getConfigClass());
                LifecycleListener listener = (LifecycleListener) clazz.getConstructor().newInstance();
                context.addLifecycleListener(listener);
    
                context.setName(cn.getName());
                context.setPath(cn.getPath());
                context.setWebappVersion(cn.getVersion());
                context.setDocBase(cn.getBaseName());
                host.addChild(context);
            } catch (Throwable t) {
                ExceptionUtils.handleThrowable(t);
                log.error(sm.getString("hostConfig.deployDir.error",
                        dir.getAbsolutePath()), t);
            } finally {
                deployedApp = new DeployedApplication(cn.getName(),
                        xml.exists() && deployThisXML && copyThisXml);
    
                // Fake re-deploy resource to detect if a WAR is added at a later
                // point
                deployedApp.redeployResources.put(dir.getAbsolutePath() + ".war",
                        Long.valueOf(0));
                deployedApp.redeployResources.put(dir.getAbsolutePath(),
                        Long.valueOf(dir.lastModified()));
                if (deployThisXML && xml.exists()) {
                    if (copyThisXml) {
                        deployedApp.redeployResources.put(
                                xmlCopy.getAbsolutePath(),
                                Long.valueOf(xmlCopy.lastModified()));
                    } else {
                        deployedApp.redeployResources.put(
                                xml.getAbsolutePath(),
                                Long.valueOf(xml.lastModified()));
                        // Fake re-deploy resource to detect if a context.xml file is
                        // added at a later point
                        deployedApp.redeployResources.put(
                                xmlCopy.getAbsolutePath(),
                                Long.valueOf(0));
                    }
                } else {
                    // Fake re-deploy resource to detect if a context.xml file is
                    // added at a later point
                    deployedApp.redeployResources.put(
                            xmlCopy.getAbsolutePath(),
                            Long.valueOf(0));
                    if (!xml.exists()) {
                        deployedApp.redeployResources.put(
                                xml.getAbsolutePath(),
                                Long.valueOf(0));
                    }
                }
                addWatchedResources(deployedApp, dir.getAbsolutePath(), context);
                // Add the global redeploy resources (which are never deleted) at
                // the end so they don't interfere with the deletion process
                addGlobalRedeployResources(deployedApp);
            }
    
            deployed.put(cn.getName(), deployedApp);
    
            if( log.isInfoEnabled() ) {
                log.info(sm.getString("hostConfig.deployDir.finished",
                        dir.getAbsolutePath(), Long.valueOf(System.currentTimeMillis() - startTime)));
            }
        }
  • 相关阅读:
    谈谈我对服务熔断、服务降级的理解
    PS-AXI-GPIO-流水灯设计
    立创EDA的使用
    multisim的操作回顾
    verilog的文件流和项目流
    AXI4的主从机的收发机制
    AXI4协议的物理模型
    verilog中的数据类型
    matlab的基本操作
    ARM之AXI总线协议初试
  • 原文地址:https://www.cnblogs.com/honger/p/10363046.html
Copyright © 2020-2023  润新知