博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tomcat war包部署
阅读量:5786 次
发布时间:2019-06-18

本文共 7799 字,大约阅读时间需要 25 分钟。

开篇

 这篇文章主要针对Tomcat针对War包部署进行一些常用的逻辑判断,这部分的核心逻辑主要回答了以下几个问题(这部分其实说实话我也不是特别明白)。

1、Context对象的创建。

2、配置变更重新部署的前置处理。
3、核心逻辑在于Context启动过程,但是这部分后面由单独的文章进行说明。

部署过程

  • 1、对于Host的appBase目录下所有符合条件的war包,由线程池完成部署。
  • 2、针对每个war包,按照如下逻辑进行判断创建StandardContext对象

    • 条件判断一:如果Host的deployXML属性为True,且在War包的同名目录下存在META-INF/context.xml文件,同时Context的copyXML属性为false,则用该context.xml创建Context实例。
    • 条件判断二:如果Host的deployXML属性为True,且在War包压缩文件下存在META-INF/context.xml文件,则使用该文件创建Context对象。
    • 条件判断三:如果deployXML属性为true,且在War包压缩文件下存在META-INF/context.xml文件,则构造FailedContext对象。
    • 条件判断四:其他情况下以contextClass属性指定的类型创建Context对象,不指定则用org.apache.catalina.core.StandardContext来进行创建。
  • 3、为Context实例添加ContextConfig生命周期监听器。
  • 4、通过Host的addChild()方法将Context实例添加到Host。该方法会判断Host是否启动,如果已启动则直接启动Context对象。
  • 5、将Context描述文件、War包及web.xml等资源添加到守护资源,以便文件发生变更时重新部署及加载Web应用。

源码解析

public class HostConfig implements LifecycleListener {    protected void deployWAR(ContextName cn, File war) {        // 在War包的同名目录下的META-INF/context.xml文件        File xml = new File(host.getAppBaseFile(),                cn.getBaseName() + "/" + Constants.ApplicationContextXml);        File warTracker = new File(host.getAppBaseFile(), cn.getBaseName() + Constants.WarTracker);        boolean xmlInWar = false;        try (JarFile jar = new JarFile(war)) {            JarEntry entry = jar.getJarEntry(Constants.ApplicationContextXml);            if (entry != null) {                xmlInWar = true;            }        } catch (IOException e) {        }        // 判断在War包的同名目录下存在META-INF/context.xml文件        boolean useXml = false;        if (xml.exists() && unpackWARs &&                (!warTracker.exists() || warTracker.lastModified() == war.lastModified())) {            useXml = true;        }        Context context = null;        boolean deployThisXML = isDeployThisXML(war, cn);        // 按照如下逻辑进行判断创建StandardContext对象        try {            // 使用War包的同名目录下存在META-INF/context.xml文件创建StandardContext对象            if (deployThisXML && useXml && !copyXML) {                synchronized (digesterLock) {                    try {                        context = (Context) digester.parse(xml);                    } catch (Exception e) {                    } finally {                        digester.reset();                        if (context == null) {                            context = new FailedContext();                        }                    }                }                context.setConfigFile(xml.toURI().toURL());            } else if (deployThisXML && xmlInWar) {                //  // 使用War包内的META-INF/context.xml文件创建StandardContext对象                synchronized (digesterLock) {                    try (JarFile jar = new JarFile(war)) {                        JarEntry entry = jar.getJarEntry(Constants.ApplicationContextXml);                        try (InputStream istream = jar.getInputStream(entry)) {                            context = (Context) digester.parse(istream);                        }                    } catch (Exception e) {                    } finally {                        digester.reset();                        if (context == null) {                            context = new FailedContext();                        }                        context.setConfigFile(                                UriUtil.buildJarUrl(war, Constants.ApplicationContextXml));                    }                }            } else if (!deployThisXML && xmlInWar) {            } else {                // 使用contextClass属性指定的类型创建Context对象,                // 不指定则用org.apache.catalina.core.StandardContext来进行创建。                context = (Context) Class.forName(contextClass).getConstructor().newInstance();            }        } catch (Throwable t) {        } finally {            if (context == null) {                context = new FailedContext();            }        }        boolean copyThisXml = false;        if (deployThisXML) {            if (host instanceof StandardHost) {                copyThisXml = ((StandardHost) host).isCopyXML();            }            if (!copyThisXml && context instanceof StandardContext) {                copyThisXml = ((StandardContext) context).getCopyXML();            }            if (xmlInWar && copyThisXml) {                // Change location of XML file to config base                xml = new File(host.getConfigBaseFile(),                        cn.getBaseName() + ".xml");                try (JarFile jar = new JarFile(war)) {                    JarEntry entry = jar.getJarEntry(Constants.ApplicationContextXml);                    try (InputStream istream = jar.getInputStream(entry);                            FileOutputStream fos = new FileOutputStream(xml);                            BufferedOutputStream ostream = new BufferedOutputStream(fos, 1024)) {                        byte buffer[] = new byte[1024];                        while (true) {                            int n = istream.read(buffer);                            if (n < 0) {                                break;                            }                            ostream.write(buffer, 0, n);                        }                        ostream.flush();                    }                } catch (IOException e) {                    /* Ignore */                }            }        }        DeployedApplication deployedApp = new DeployedApplication(cn.getName(),                xml.exists() && deployThisXML && copyThisXml);        try {            deployedApp.redeployResources.put                (war.getAbsolutePath(), Long.valueOf(war.lastModified()));            if (deployThisXML && xml.exists() && copyThisXml) {                deployedApp.redeployResources.put(xml.getAbsolutePath(),                        Long.valueOf(xml.lastModified()));            } else {                // In case an XML file is added to the config base later                deployedApp.redeployResources.put(                        (new File(host.getConfigBaseFile(),                                cn.getBaseName() + ".xml")).getAbsolutePath(),                        Long.valueOf(0));            }            // 通过Host的addChild()方法将Context实例添加到Host            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() + ".war"); // 添加Context对象到StandardHost对象当中, // 如果Host已启动那么同事启动Context对象。 host.addChild(context); } catch (Throwable t) { } finally { // 将Context描述文件、War包及web.xml等资源添加到守护资源, // 以便文件发生变更时重新部署及加载Web应用。 boolean unpackWAR = unpackWARs; if (unpackWAR && context instanceof StandardContext) { unpackWAR = ((StandardContext) context).getUnpackWAR(); } if (unpackWAR && context.getDocBase() != null) { File docBase = new File(host.getAppBaseFile(), cn.getBaseName()); deployedApp.redeployResources.put(docBase.getAbsolutePath(), Long.valueOf(docBase.lastModified())); addWatchedResources(deployedApp, docBase.getAbsolutePath(), context); if (deployThisXML && !copyThisXml && (xmlInWar || xml.exists())) { deployedApp.redeployResources.put(xml.getAbsolutePath(), Long.valueOf(xml.lastModified())); } } else { addWatchedResources(deployedApp, null, context); } addGlobalRedeployResources(deployedApp); } deployed.put(cn.getName(), deployedApp); }}

转载地址:http://dityx.baihongyu.com/

你可能感兴趣的文章
Windows Message Queue
查看>>
区间DP(区间最优解)题目讲解总结
查看>>
针对MySql封装的JDBC通用框架类(包含增删改查、JavaBean反射原理)
查看>>
转载: HDMI 基础知识
查看>>
EAC3 Transient Pre-Noise Processing
查看>>
Swift Realm 完整使用记录
查看>>
memcached 在windows中的部署和使用
查看>>
详解js变量、作用域及内存
查看>>
[LeetCode] Two Sum, Solution
查看>>
网络流24题 -No.18 分配问题
查看>>
mysql 5.7版本目录无data文件夹的解决办法
查看>>
源码分析 脱壳神器ZjDroid工作原理
查看>>
gcc与g++
查看>>
spring读取多个配置properties报错"Could not resolve placeholder"的解决方案
查看>>
SqlDataReader引起的超时?
查看>>
获得表中字段说明
查看>>
推荐系统-05-Spark电影推荐、评估与部署
查看>>
WCF入门(一)——基本知识
查看>>
MongoDb 快速入门教程
查看>>
java中的socket编程有关printStream的println方法和write方法
查看>>