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)));
}
}

context创建过程解析(三)之deployDirectories的更多相关文章

  1. context创建过程解析(一)之deployDescriptors

    总结:主要是创建Context对象,并且将默认context配置,host级别配置,context配置的值设置进去,设置docBase,如果是war包就解压到webapp的目录中,重新设置docBas ...

  2. context创建过程解析(二)之deployWARs

    HostConfig.deployApps() //在监听到start事件类型,也就是StandardHost调用startInternal protected void deployApps() { ...

  3. Android深入理解Context(一)Context关联类和Application Context创建过程

    前言 Context也就是上下文对象,是Android较为常用的类,但是对于Context,很多人都停留在会用的阶段,这个系列会带大家从源码角度来分析Context,从而更加深入的理解它. 1.Con ...

  4. Android深入理解Context(二)Activity和Service的Context创建过程

    前言 上一篇文章我们学习了Context关联类和Application Context的创建过程,这一篇我们接着来学习Activity和Service的Context创建过程.需要注意的是,本篇的知识 ...

  5. ZooKeeper(三):请求处理链路的创建过程解析

    我们知道,zk就是一个个处理链组成的. 但是,这些处理链是在什么创建的呢? ZooKeeper 中有三种角色的服务节点存在: Leader, Follower, Observer . 而每个服务节点的 ...

  6. JVM系列(三):JVM创建过程解析

    上两篇中梳理了整个java启动过程中,jvm大致是如何运行的.即厘清了我们认为的jvm的启动过程.但那里面仅为一些大致的东西,比如参数解析,验证,dll加载等等.把最核心的loadJavaVM()交给 ...

  7. InputSplit—>RecordReder—>map(key,value,context)的过程解析

    上图首先描述了在TaskTracker端Task(MapTask.ReduceTask)的执行过程,MapTask(org.apache.hadoop.mapred)首先被TaskRunner调用,然 ...

  8. Android Context创建过程

        特定的资源或者类构成了Android应用程序的运行上下文环境 PackageManager, ClassLoader, Assert等等 Android应用程序窗口的运行上下文环境是通过Con ...

  9. [原创]Andorid DexClassLoader的创建过程解析(基于5.0)

    做Android插件框架时,经常会用到dex的动态加载,就要直接或间接的使用DexClassLoader,在new DexClassLoader的时候Android系统做了很多工作,下面我们详细分析一 ...

随机推荐

  1. javascript“命名空间”的费曼输出[原创]

    Javascript由于没有命名空间的概念,所以好多的框架或库就用了某些“命名空间”的技巧.在学习作为函数的命名空间时,我翻阅了好多的书本和blog,很多的概念和说明都是要么过于烦杂或过于简单.现在由 ...

  2. vue history 模式打包部署在域名的二级目录的配置指南

    最近在做项目,需要把项目部署在域名下的二级目录,并且是在用vue-router的history 模式. 我们都知道vue-router 的两种前端基本访问模式 hash 和history .hash ...

  3. 预习初三物理电学部分的心得体会&知识梳理(持续更新)

    DAY 1 一.摩擦起电 用摩擦的方式使两个不同的物体带电的现象. 二.带电体 如果一个物体能够吸引轻小物体,我们就说这个物体带电或者说带了电荷. (注:吸引轻小物体是作用效果,带电体对任何物体都有吸 ...

  4. Consul&Nginx&Registrator&ConsulTemplate部署高可用负载均衡

    1. Consul Server 创建consul server虚拟主机 docker-machine create consul 出现如下内容即创建成功 Running pre-create che ...

  5. NoSQL数据库兴起

    前言 近几年NoSQL数据库兴起,各种新的产品层出不穷,在此学习下NoSQL的基本理论,并认识下常见的NoSQL数据库. 一 NoSQL数据库兴起的原因 随着大数据技术兴起和Web2.0时代的到来.传 ...

  6. C#—使用InstallerProjects打包桌面应用程序

    前言 打包桌面应用程序实在是一个不常使用的东西,偶尔使用起来经常会忘东忘西的耽误时间,因此,这篇文章多以图片记录过程,也是用于备忘. 下载打包工具 C#打包桌面应用程序有很多种方法,这里介绍一种使用M ...

  7. 如何使用 Docker 安装 Jenkins

    说在前面 本篇内容非常简单,仅讲述了如何快速在 Docker 上部署一个 Jenkins 实例,不涉及其他. 本文实验环境: 操作系统:Centos 7.5 Docker Version:18.09. ...

  8. HTTP 学习笔记01

    HTTP   hypertext transfer protocol (超文本传输协议) TCP/IP 协议集中的一个应用层协议 用于定义WEB浏览器与WEB服务器之间交换数据的过程以及数据本身的格式 ...

  9. HDU 5773:The All-purpose Zero(贪心+LIS)

    http://acm.hdu.edu.cn/showproblem.php?pid=5773 The All-purpose Zero Problem Description   ?? gets an ...

  10. Flink会话窗口测试

    Flink会话窗口测试 一.测试结论: 1.会话窗口的间隔时间和水位线作用一样,表示输出现在时间 - 间隔时间之前所有未结算时间的数据,作用类似于水位线,但是和水位线开闭不一样. 2.会话窗口显示的数 ...