天天看點

簡單介紹下tomcat的三種部署方式前言一、deployDescriptors二、WAR封包件部署三、檔案夾部署總結

tomcat部署的三種方式
           

前言

年輕人不講武德,第一次寫部落格,還請大佬手下留情!! 多多指教 。本人菜鳥一枚第一次研究tomcat源碼,簡單的看了下源碼,發現了tomcat的三種部署方式(實際四種,但本人隻描述三種方式):

// Deploy XML descriptors from configBase(檔案描述符的方式部署)

方式-1.deployDescriptors(configBase, configBase.list());

// Deploy WARs(war包的方式部署)

方式-2.deployWARs(appBase, filteredAppPaths);

// Deploy expanded folders(檔案夾的方式部署)

方式- 3.deployDirectories(appBase, filteredAppPaths);

至于我為啥知道有這三種方式部署,因為看的tomcat的源碼(類HostConfig-》method deployApps 哈哈 本人喜歡裝逼 !!!!

簡單介紹下tomcat的三種部署方式前言一、deployDescriptors二、WAR封包件部署三、檔案夾部署總結

一、deployDescriptors

翻譯:部署XML上下文描述符

/**
     * Deploy XML context descriptors.
     * @param configBase The config base
     * @param files The XML descriptors which should be deployed
     */
    protected void deployDescriptors(File configBase, String[] files) {

        if (files == null)
            return;

        ExecutorService es = host.getStartStopExecutor();
        List<Future<?>> results = new ArrayList<>();

        for (String file : files) {
            File contextXml = new File(configBase, file);

            if (file.toLowerCase(Locale.ENGLISH).endsWith(".xml")) {
                ContextName cn = new ContextName(file, true);

                if (isServiced(cn.getName()) || deploymentExists(cn.getName()))
                    continue;

                results.add(
                        es.submit(new DeployDescriptor(this, cn, contextXml)));
            }
        }

        for (Future<?> result : results) {
            try {
                result.get();
            } catch (Exception e) {
                log.error(sm.getString(
                        "hostConfig.deployDescriptor.threaded.error"), e);
            }
        }
    }
           

二、WAR封包件部署

/**
     * Deploy WAR files.
     * @param appBase The base path for applications
     * @param files The WARs to deploy
     */
    protected void deployWARs(File appBase, String[] files) {

        if (files == null)
            return;

        ExecutorService es = host.getStartStopExecutor();
        List<Future<?>> results = new ArrayList<>();

        for (String file : files) {

            if (file.equalsIgnoreCase("META-INF"))
                continue;
            if (file.equalsIgnoreCase("WEB-INF"))
                continue;
            File war = new File(appBase, file);
            if (file.toLowerCase(Locale.ENGLISH).endsWith(".war") &&
                    war.isFile() && !invalidWars.contains(file)) {

                ContextName cn = new ContextName(file, true);

                if (isServiced(cn.getName())) {
                    continue;
                }
                if (deploymentExists(cn.getName())) {
                    DeployedApplication app = deployed.get(cn.getName());
                    boolean unpackWAR = unpackWARs;
                    if (unpackWAR && host.findChild(cn.getName()) instanceof StandardContext) {
                        unpackWAR = ((StandardContext) host.findChild(cn.getName())).getUnpackWAR();
                    }
                    if (!unpackWAR && app != null) {
                        // Need to check for a directory that should not be
                        // there
                        File dir = new File(appBase, cn.getBaseName());
                        if (dir.exists()) {
                            if (!app.loggedDirWarning) {
                                log.warn(sm.getString(
                                        "hostConfig.deployWar.hiddenDir",
                                        dir.getAbsoluteFile(),
                                        war.getAbsoluteFile()));
                                app.loggedDirWarning = true;
                            }
                        } else {
                            app.loggedDirWarning = false;
                        }
                    }
                    continue;
                }

                // Check for WARs with /../ /./ or similar sequences in the name
                if (!validateContextPath(appBase, cn.getBaseName())) {
                    log.error(sm.getString(
                            "hostConfig.illegalWarName", file));
                    invalidWars.add(file);
                    continue;
                }

                results.add(es.submit(new DeployWar(this, cn, war)));
            }
        }

        for (Future<?> result : results) {
            try {
                result.get();
            } catch (Exception e) {
                log.error(sm.getString(
                        "hostConfig.deployWar.threaded.error"), e);
            }
        }
    }
           

三、檔案夾部署

/**
     * Deploy exploded webapps.
     * @param appBase The base path for applications
     * @param files The exploded webapps that should be deployed
     */
    protected void deployDirectories(File appBase, String[] files) {

        if (files == null)
            return;

        ExecutorService es = host.getStartStopExecutor();
        List<Future<?>> results = new ArrayList<>();

        for (String file : files) {

            if (file.equalsIgnoreCase("META-INF"))
                continue;
            if (file.equalsIgnoreCase("WEB-INF"))
                continue;
            File dir = new File(appBase, file);
            if (dir.isDirectory()) {
                ContextName cn = new ContextName(file, 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);
            }
        }
    }
           

總結

看了上面的代碼,相信許多同學知道了為啥部署到tomcat上的項目必須要以war包的形式部署了吧,因為tomcat源碼寫死了去比對war包,而不支援jar包的形式部署了吧,其實還有一個原因就是jar包本身可以了解為依賴,tomcat無法識别這個jar是項目的依賴 還是 web應用,所有隻識别了war包的部署,而本身war包和jar包沒有本質的差別(如有不對的地方,歡迎大佬來怼,奧利給!)