(七)Tomcat源码阅读:Host组件分析

一、概述

Host类中比较重要的类就是HostConfig其它类实现的功能和之前的组件差不多,这里就不多介绍了。

二、阅读源码

1、HostConfig

(1)重要方法

lifecycleEvent:

根据对应的方法设置对应的属性,并调用对应的方法。

 @Override
    public void lifecycleEvent(LifecycleEvent event) {

        // Identify the host we are associated with
        try {
            host = (Host) event.getLifecycle();
            if (host instanceof StandardHost) {
                setCopyXML(((StandardHost) host).isCopyXML());
                setDeployXML(((StandardHost) host).isDeployXML());
                setUnpackWARs(((StandardHost) host).isUnpackWARs());
                setContextClass(((StandardHost) host).getContextClass());
            }
        } catch (ClassCastException e) {
            log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e);
            return;
        }

        // Process the event that has occurred
        if (event.getType().equals(Lifecycle.PERIODIC_EVENT)) {
            check();
        } else if (event.getType().equals(Lifecycle.BEFORE_START_EVENT)) {
            beforeStart();
        } else if (event.getType().equals(Lifecycle.START_EVENT)) {
            start();
        } else if (event.getType().equals(Lifecycle.STOP_EVENT)) {
            stop();
        }
    }

beforeStart:

beforeStart创建了如下图的两个目录。

   public void beforeStart() {
        if (host.getCreateDirs()) {
            File[] dirs = new File[] {host.getAppBaseFile(),host.getConfigBaseFile()};
            for (File dir : dirs) {
                if (!dir.mkdirs() && !dir.isDirectory()) {
                    log.error(sm.getString("hostConfig.createDirs", dir));
                }
            }
        }
    }

 start:

start调用了deployApps部署对应的App。

    public void start() {

        if (log.isDebugEnabled()) {
            log.debug(sm.getString("hostConfig.start"));
        }

        try {
            ObjectName hostON = host.getObjectName();
            oname = new ObjectName
                (hostON.getDomain() + ":type=Deployer,host=" + host.getName());
            Registry.getRegistry(null, null).registerComponent
                (this, oname, this.getClass().getName());
        } catch (Exception e) {
            log.warn(sm.getString("hostConfig.jmx.register", oname), e);
        }

        if (!host.getAppBaseFile().isDirectory()) {
            log.error(sm.getString("hostConfig.appBase", host.getName(),
                    host.getAppBaseFile().getPath()));
            host.setDeployOnStartup(false);
            host.setAutoDeploy(false);
        }

        if (host.getDeployOnStartup()) {
            deployApps();
        }
    }

deployApps:

    protected void deployApps() {
        File appBase = host.getAppBaseFile();
        File configBase = host.getConfigBaseFile();
        String[] filteredAppPaths = filterAppPaths(appBase.list());
        // Deploy XML descriptors from configBase
        deployDescriptors(configBase, configBase.list());
        // Deploy WARs
        deployWARs(appBase, filteredAppPaths);
        // Deploy expanded folders
        deployDirectories(appBase, filteredAppPaths);
    }

deployDescriptors:

根据xml文件部署应用。

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 (tryAddServiced(cn.getName())) {
                    try {
                        if (deploymentExists(cn.getName())) {
                            removeServiced(cn.getName());
                            continue;
                        }

                        // DeployDescriptor will call removeServiced
                        results.add(es.submit(new DeployDescriptor(this, cn, contextXml)));
                    } catch (Throwable t) {
                        ExceptionUtils.handleThrowable(t);
                        removeServiced(cn.getName());
                        throw t;
                    }
                }
            }
        }

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

deployWARs:

根据war包部署文件。

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 (tryAddServiced(cn.getName())) {
                    try {
                        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;
                                }
                            }
                            removeServiced(cn.getName());
                            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);
                            removeServiced(cn.getName());
                            continue;
                        }

                        // DeployWAR will call removeServiced
                        results.add(es.submit(new DeployWar(this, cn, war)));
                    } catch (Throwable t) {
                        ExceptionUtils.handleThrowable(t);
                        removeServiced(cn.getName());
                        throw t;
                    }
                }
            }
        }

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

deployDirectories:

根据文件夹部署文件。

 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 (tryAddServiced(cn.getName())) {
                    try {
                        if (deploymentExists(cn.getName())) {
                            removeServiced(cn.getName());
                            continue;
                        }

                        // DeployDirectory will call removeServiced
                        results.add(es.submit(new DeployDirectory(this, cn, dir)));
                    } catch (Throwable t) {
                        ExceptionUtils.handleThrowable(t);
                        removeServiced(cn.getName());
                        throw t;
                    }
                }
            }
        }

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

check :

监听资源是否变动,变动的话就刷新上下文或者重新部署。

protected void check() {

        if (host.getAutoDeploy()) {
            // Check for resources modification to trigger redeployment
            DeployedApplication[] apps = deployed.values().toArray(new DeployedApplication[0]);
            for (DeployedApplication app : apps) {
                if (tryAddServiced(app.name)) {
                    try {
                        checkResources(app, false);
                    } finally {
                        removeServiced(app.name);
                    }
                }
            }

            // Check for old versions of applications that can now be undeployed
            if (host.getUndeployOldVersions()) {
                checkUndeploy();
            }

            // Hotdeploy applications
            deployApps();
        }
    }

 checkResources:

check方法具体调用的监听方法。

protected synchronized void checkResources(DeployedApplication app,
            boolean skipFileModificationResolutionCheck) {
        String[] resources =
            app.redeployResources.keySet().toArray(new String[0]);
        // Offset the current time by the resolution of File.lastModified()
        long currentTimeWithResolutionOffset =
                System.currentTimeMillis() - FILE_MODIFICATION_RESOLUTION_MS;
        for (int i = 0; i < resources.length; i++) {
            File resource = new File(resources[i]);
            if (log.isDebugEnabled()) {
                log.debug("Checking context[" + app.name +
                        "] redeploy resource " + resource);
            }
            long lastModified =
                    app.redeployResources.get(resources[i]).longValue();
            if (resource.exists() || lastModified == 0) {
                // File.lastModified() has a resolution of 1s (1000ms). The last
                // modified time has to be more than 1000ms ago to ensure that
                // modifications that take place in the same second are not
                // missed. See Bug 57765.
                if (resource.lastModified() != lastModified && (!host.getAutoDeploy() ||
                        resource.lastModified() < currentTimeWithResolutionOffset ||
                        skipFileModificationResolutionCheck)) {
                    if (resource.isDirectory()) {
                        // No action required for modified directory
                        app.redeployResources.put(resources[i],
                                Long.valueOf(resource.lastModified()));
                    } else if (app.hasDescriptor &&
                            resource.getName().toLowerCase(
                                    Locale.ENGLISH).endsWith(".war")) {
                        // Modified WAR triggers a reload if there is an XML
                        // file present
                        // The only resource that should be deleted is the
                        // expanded WAR (if any)
                        Context context = (Context) host.findChild(app.name);
                        String docBase = context.getDocBase();
                        if (!docBase.toLowerCase(Locale.ENGLISH).endsWith(".war")) {
                            // This is an expanded directory
                            File docBaseFile = new File(docBase);
                            if (!docBaseFile.isAbsolute()) {
                                docBaseFile = new File(host.getAppBaseFile(),
                                        docBase);
                            }
                            reload(app, docBaseFile, resource.getAbsolutePath());
                        } else {
                            reload(app, null, null);
                        }
                        // Update times
                        app.redeployResources.put(resources[i],
                                Long.valueOf(resource.lastModified()));
                        app.timestamp = System.currentTimeMillis();
                        boolean unpackWAR = unpackWARs;
                        if (unpackWAR && context instanceof StandardContext) {
                            unpackWAR = ((StandardContext) context).getUnpackWAR();
                        }
                        if (unpackWAR) {
                            addWatchedResources(app, context.getDocBase(), context);
                        } else {
                            addWatchedResources(app, null, context);
                        }
                        return;
                    } else {
                        // Everything else triggers a redeploy
                        // (just need to undeploy here, deploy will follow)
                        undeploy(app);
                        deleteRedeployResources(app, resources, i, false);
                        return;
                    }
                }
            } else {
                // There is a chance the the resource was only missing
                // temporarily eg renamed during a text editor save
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e1) {
                    // Ignore
                }
                // Recheck the resource to see if it was really deleted
                if (resource.exists()) {
                    continue;
                }
                // Undeploy application
                undeploy(app);
                deleteRedeployResources(app, resources, i, true);
                return;
            }
        }
        resources = app.reloadResources.keySet().toArray(new String[0]);
        boolean update = false;
        for (String s : resources) {
            File resource = new File(s);
            if (log.isDebugEnabled()) {
                log.debug("Checking context[" + app.name + "] reload resource " + resource);
            }
            long lastModified = app.reloadResources.get(s).longValue();
            // File.lastModified() has a resolution of 1s (1000ms). The last
            // modified time has to be more than 1000ms ago to ensure that
            // modifications that take place in the same second are not
            // missed. See Bug 57765.
            if ((resource.lastModified() != lastModified &&
                    (!host.getAutoDeploy() ||
                            resource.lastModified() < currentTimeWithResolutionOffset ||
                            skipFileModificationResolutionCheck)) ||
                    update) {
                if (!update) {
                    // Reload application
                    reload(app, null, null);
                    update = true;
                }
                // Update times. More than one file may have been updated. We
                // don't want to trigger a series of reloads.
                app.reloadResources.put(s,
                        Long.valueOf(resource.lastModified()));
            }
            app.timestamp = System.currentTimeMillis();
        }
    }

(2)处理流程

lifecycleEvent调用start()方法,start()方法再调用deployApps()方法,deployApps()方法根据情况分别调用deployDescriptors,deployWARs,deployDirectories创建应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/5420.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自己写gpt的软件教程-国内最好的chatgpt软件

GPT-3是一种非常强大的自然语言处理技术&#xff0c;可以为用户生成高质量的文本内容。虽然GPT-3最初是为英文而设计的&#xff0c;但是近年来&#xff0c;GPT-3在中文领域也变得越来越流行。在本篇教程中&#xff0c;我们将详细介绍如何在GPT-3中生成中文内容。 一、准备工作 …

第二天并发篇

一、线程状态 1.新建&#xff08;New&#xff09;&#xff1a;创建线程对象时 2.就绪&#xff08;Runnable&#xff09;&#xff1a;线程调用start方法&#xff0c;有执行资格没有执行权 3.运行&#xff1a;当就绪状态时抢到cpu的执行权之后&#xff0c;进入运行状态 4.阻塞&am…

过程控制系统中的模块技术MTP

在过程自动化行业中&#xff0c;模块化设备概念近年来越来越受欢迎。其中最热门的是MTP。MTP称为模块类型封装&#xff0c;它是过程工业自动化技术用户协会&#xff08;NAMUR&#xff09;提出的过程自动化行业的模块化标准&#xff0c;通过这种模型&#xff0c;开发工作的重点从…

C++(Qt)软件调试---linux下生成/调试Core文件(3)

#软件调试 C(Qt)软件调试—linux下生成/调试Core文件&#xff08;3&#xff09; 文章目录C(Qt)软件调试---linux下生成/调试Core文件&#xff08;3&#xff09;前言1、C生成Core和使用GDB调试1、环境2、C生成Core文件3、使用gdb工具调试core可定位段错误位置&#xff1b;4、修…

【创作赢红包】你是真的“C”——C语言中文件操作函数使用的详细讲解【上篇】

你是真的“c”——C语言中文件操作函数使用的详细讲解~&#x1f60e;前言&#x1f64c;一、 为什么使用文件&#xff1a;&#x1f64c;二、 什么是文件&#xff1a;&#x1f64c;2.1 程序文件2.2 数据文件2.3 文件名3. 文件的打开和关闭3.1 文件指针3.2 文件的打开和关闭4. 文件…

【ansible】实施任务控制

目录 实施任务控制 一&#xff0c;循环&#xff08;迭代&#xff09;--- loop 1&#xff0c;利用loop----item循环迭代任务 2&#xff0c;item---loop循环案例 1&#xff0c;定义item循环列表 2&#xff0c;通过变量应用列表格式 3&#xff0c;字典列表&#xff08;迭代嵌套子…

一个ESP32小东西

之前发了ESP8266&#xff0c;有人评论说玩下ESP32然后就买了几个回来&#xff0c;当然&#xff0c;也想着和大家一起玩介绍下这个开发板开发板Github项目链接https://github.com/Xinyuan-LilyGO/T-QT把仓库的代码下载到本地我们可以用ESP-IDF和Arduino两个SDK来开发ESP32S3ESP-…

回溯算法思想、回溯算法解题模板与回溯算法题目索引(不断更新)

回溯算法 回溯算法是一种试探性的搜索算法&#xff0c;它在解决某些组合问题、优化问题、路径问题等&#xff0c;非常有效。回溯算法的核心思想是通过递归和深度优先搜索&#xff08;DFS&#xff09;来搜索问题的解空间。 细说一下这些问题&#xff1a; 组合问题&#xff1a;N…

初级网络工程师这30道面试题一定得会,建议小白收藏!

你好&#xff0c;这里是网络技术联盟站。 后台有小伙伴想让瑞哥整理一下初级网络工程师面试题&#xff0c;今天我整理出来了&#xff0c;针对初级网络工程师&#xff0c;我们在面试的时候主要考察的是基础概念&#xff0c;下面列举的希望大家可以收藏&#xff0c;平时多看看&a…

活动选择问题 | 贪心算法 1

贪心法是一种算法范式&#xff0c;它逐个构建解决方案&#xff0c;始终选择下一个提供最明显和最直接好处的部分。贪心算法用于优化问题。 如果问题具有以下属性&#xff0c;则可以使用 Greedy 解决优化问题&#xff1a; 在每一步中&#xff0c;我们都可以做出当前看起来最好…

MongoDB 6.0 (四)聚合操作

一、 聚合框架的作用 1. 什么是MongoDB 聚合框架 MongoDB 聚合框架(Aggregation Framework)是一个计算框架,它可以: • 作用在一个或几个集合上; • 对集合中的数据进行的一系列运算; • 将这些数据转化为期望的形式; 从效果而言,聚合框架相当于SQL 查询中的: …

【Mysql系列】——详细剖析数据库“索引”【上篇】

【Mysql系列】——详细剖析数据库中的核心知识【索引】&#x1f60e;前言&#x1f64c;索引索引概述为什么需要索引&#xff1f;索引的优缺点索引结构索引的结构为什么不是二叉树和红黑树&#xff1f;索引的B树结构索引的Hash结构Hash结构索引的特点思考&#xff1a;为什么Inno…

MySQL中多表查询(多表关系:一对多、多对多、一对一,分类:连接查询:内连接、外连接、自连接、联合查询,子查询:标量子查询、列子查询、行子查询、表子查询)

多表关系&#xff1a; 一对多&#xff1a; 多对多&#xff1a; 一对一&#xff1a; 我们发现我们利用DQL中的select语句查询多张表的时候&#xff0c;会出现一个数学现象&#xff0c;叫做笛卡尔积 因此我们可以加上where语句来限定条件&#xff1a; 内连接&#xff1a; 此处in…

计算机网络面试八股文攻略(一) —— OSI 七层模型

一、简述 本系列将对面试中与计算机网络相关的知识进行讲解与分析。 本篇为 OSI 七层网络模型的相关知识。 二、概念 OSI 七层网络模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间互联的标准体系。它是一个七层的、抽象的模型体&#xff…

A Causal Debiasing Framework for Unsupervised Salient Object Detection

背景知识 显著性检测 简单就是使用图像处理技术和计算机视觉算法来定位图片中最“显著”的区域。显著区域就是指图片中引人注目的区域或比较重要的区域&#xff0c;例如人眼在观看一幅图片时会首先关注的区域。 chatGPT4的回答 计算机视觉中的显著性检测&#xff08;Visual…

从事6个月软件测试,目前只会功能测试迷茫了...

前言 (来自一位粉丝的投稿)来这个公司大半年&#xff0c;现在主要做的是类似于淘宝的购物商城&#xff0c;以前也做应用系统什么的&#xff0c;可是感觉公司的软件测试岗位都是不着边的&#xff0c;因为做的都是功能测试&#xff0c;来了这么久&#xff0c;没接触过技术性的东…

美丽苏大,清华博士,年轻硕导,招收研究生了!

Datawhale学术 导师&#xff1a;张正超&#xff0c;苏州大学&#xff0c;Datawhale成员导师信息本人于2022年取得清华大学博士学位&#xff0c;目前是苏州大学计算机科学与技术学院的硕士生导师&#xff0c;2023年可招收计算机科学与技术、软件工程、人工智能及大数据技术与工程…

微服务保护Sentinel一站式学习

微服务保护Sentinel 雪崩问题 解决雪崩问题的四种常见方式&#xff1a; 超时处理&#xff1a;设定超时时间&#xff0c;请求超过一定时间没有响应就返回错误信息&#xff0c;不会无休止等待。如果设置一秒钟没响应返回&#xff0c;即1s释放连接&#xff0c;这1s中有好多个请求…

BOSS直拒、失联招聘,消失的“金三银四”,失业的测试人出路在哪里?

裁员潮涌&#xff0c;经济严冬。最近很多测试人过得并不好&#xff0c;行业缩水对测试岗位影响很直接干脆&#xff0c;究其原因还是测试门槛在IT行业较低&#xff0c;同质化测试人员比较多。但实际上成为一位好测试却有着较高的门槛&#xff0c;一名优秀的测试应当对产品的深层…

Stable Diffusion 视频和图片帧互换以及AI动画帧生成

Stable Diffusion 只做AI动画是基于把原有视频按照帧进行提取之后对每一帧的图像进行标准化流程操作&#xff0c;中间可以掺杂Controlnet对人物进行控制&#xff0c;使用关键词对画面进行控制&#xff0c;但是很多小伙伴不太会掌握一些编辑视频软件或者python的操作导致视频转帧…