美文网首页WebTomcat
Tomcat Web目录部署

Tomcat Web目录部署

作者: 晴天哥_王志 | 来源:发表于2018-11-10 00:13 被阅读61次

开篇

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

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

部署过程

  • 1、对于Host的appBase目录下所有符合条件的目录,由线程池完成部署。

  • 2、针对每个目录,按照如下逻辑进行判断:

    • 条件判断一:如果Host的deployXML属性值为true,并且存在META-INF/context.xml文件,则由Digester解析content.xml文件创建Context对象。

    • 条件判断二:如果Host的deployXML属性值为false,但是存在META-INF/context.xml文件,则构造FailedContext对象。

    • 条件判断三:其他情况下根据Host的contextClass属性指定的类型创建Context对象,如不指定则为org.apache.catalina.core.StandardContext。

  • 3、为Context实例添加ContextConfig生命周期监听器。

  • 4、通过Host的addChild()方法将Context实例对象添加到Host,该方法会判断Host是否启动,如果已启动则直接启动Context对象。Context的启动过程才是核心逻辑,后面会单独有文章进行说明

  • 5、将Context描述文件、Web应用目录及web.xml等添加到守护资源,以便文件发生变更时重新部署或者加载web应用。

源码解析

public class HostConfig implements LifecycleListener {

    protected void deployDirectory(ContextName cn, File dir) {

        // step1、针对Web目录进行部署
        Context context = null;
        // ApplicationContextXml = "META-INF/context.xml"
        File xml = new File(dir, Constants.ApplicationContextXml);
        File xmlCopy =
                new File(host.getConfigBaseFile(), cn.getBaseName() + ".xml");


        DeployedApplication deployedApp;
        boolean copyThisXml = isCopyXML();
        boolean deployThisXML = isDeployThisXML(dir, cn);

        try {
            // 条件判断一:如果Host的deployXML属性值为true,
            // 并且存在META-INF/context.xml文件,
            // 则由Digester解析content.xml文件创建Context对象。
            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();
                        }
                    }
                }

                if (copyThisXml == false && context instanceof StandardContext) {
                    // Host is using default value. Context may override it.
                    copyThisXml = ((StandardContext) context).getCopyXML();
                }

                if (copyThisXml) {
                    Files.copy(xml.toPath(), xmlCopy.toPath());
                    context.setConfigFile(xmlCopy.toURI().toURL());
                } else {
                    context.setConfigFile(xml.toURI().toURL());
                }
            // 条件判断二:如果Host的deployXML属性值为false,
            // 但是存在META-INF/context.xml文件,则构造FailedContext对象。
            } else if (!deployThisXML && xml.exists()) {
                // 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 {
                // 条件判断三:其他情况下根据Host的contextClass属性指定的类型创建Context对象,
                // 如不指定则为org.apache.catalina.core.StandardContext。
                context = (Context) Class.forName(contextClass).getConstructor().newInstance();
            }

            // step2、为Context实例添加ContextConfig生命周期监听器。
            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实例对象添加到Host,
            // 该方法会判断Host是否启动,如果已启动则直接启动Context对象。
            host.addChild(context);
        } catch (Throwable t) {
            ExceptionUtils.handleThrowable(t);
            log.error(sm.getString("hostConfig.deployDir.error",
                    dir.getAbsolutePath()), t);
        } finally {
            // step3、将Context描述文件、Web应用目录及web.xml等添加到守护资源,
            // 以便文件发生变更时重新部署或者加载web应用。
            deployedApp = new DeployedApplication(cn.getName(),
                    xml.exists() && deployThisXML && copyThisXml);
            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()));

                    deployedApp.redeployResources.put(
                            xmlCopy.getAbsolutePath(),
                            Long.valueOf(0));
                }
            } else {
                deployedApp.redeployResources.put(
                        xmlCopy.getAbsolutePath(),
                        Long.valueOf(0));
                if (!xml.exists()) {
                    deployedApp.redeployResources.put(
                            xml.getAbsolutePath(),
                            Long.valueOf(0));
                }
            }
            addWatchedResources(deployedApp, dir.getAbsolutePath(), context);
            addGlobalRedeployResources(deployedApp);
        }

        deployed.put(cn.getName(), deployedApp);
    }
}

相关文章

  • tomcat 部署web

    Tomcat部署web有三种方式: 一. 直接部署在Tomcat的webapps目录下: 这种方式不被推荐,项目不...

  • Tomcat Web目录部署

    开篇  这篇文章主要针对Tomcat针对Web目录部署进行一些常用的逻辑判断,这部分的核心逻辑主要回答了以下几个问...

  • [java]31、Maven

    1、Tomcat部署项目的方式 1.1、将web项目整个文件夹,放在%TOMCAT_HOME%/webapps目录...

  • JavaEE-Tomcat配置

    1.Tomcat目录结构 2.Host主机(网站) 3.WEB应用(webapp) 4.Tomcat自动部署和自动...

  • Tomcat部署Web应用方法总结

    Tomcat部署Web应用方法总结在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署。在下...

  • HttpServletResponse的应用

    快速部署一个Web应用程序 在/WebApps目录下新建一个文件夹oyty,在oyty目录...

  • tomcat部署项目的方式

    一、静态部署 1、直接将web项目文件件拷贝到webapps 目录中 Tomcat的Webap...

  • 记录解决方法

    解决Eclipse EE部署web项目在Tomcat webapp目录下没有工程文件的问题地址:https://b...

  • 1 如何优化Tomcat

    目录 Tomcat目录 Tomcat优化方向 配置项的删除 WEB-INF/web.xml conf/web.xm...

  • 在Tomcat中部署web项目的三种方式

    介绍在Tomcat中部署web项目的三种方式: 1.部署解包的webapp目录 2.打包的war文件 3.Mana...

网友评论

    本文标题:Tomcat Web目录部署

    本文链接:https://www.haomeiwen.com/subject/wquaxqtx.html