自承式光缆 私有变量 docker安装 xml postgresql haskell soap websocket hive stack sqlalchemy History.js jmeter性能测试视频 float占几个字节 打印缩放怎么设置 erp项目描述 matlab图像识别 map删除指定元素 html好看的字体 spring源码下载 oracle时间格式化 matlab读入图片 flutter ui构建工具 python开发工具 python获取字典的值 java删除数组中的元素 java中的数据结构 java定义接口 java怎么学 java比较字符串 java截取 linux下载安装 php实例 mac地址修改器 摩斯电码翻译器 神龙激活 联发科p70 stl2stp 御旌是什么 服务器系统安装
当前位置: 首页 > 学习教程  > 编程语言

Tomcat源码| HostConfig主机配置

2020/9/19 16:17:30 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

流程:

org.apache.catalina.startup.HostConfig#lifecycleEvent

组件的声明周期事件触发:
org.apache.catalina.startup.HostConfig#lifecycleEvent

    /**
     * Process the START event for an associated Host.
     *
     * @param event The lifecycle event that has occurred
     */
    @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();
        }
    }

如果是start时,则触发开始:

    /**
     * Process a "start" event for this Host.
     */
    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();

    }

发布应用只会在两个逻辑中:
程序执行start时,触发Host的声明周期事件时,和定时轮行检查web应用状态时

    /**
     * Check status of all webapps.
     */
    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 (!isServiced(app.name))
                    checkResources(app, false);
            }

            // Check for old versions of applications that can now be undeployed
            if (host.getUndeployOldVersions()) {
                checkUndeploy();
            }
             
            // 发布应用
            // Hotdeploy applications
            deployApps();
        }
    }

每一次发布应用时有三种发布方式:

    /**
     * Deploy applications for any directories or WAR files that are found
     * in our "application root" directory.
     */
    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);

    }

声明周期重复啊:
所有的config都是监听器,配置的时候会被注入到LifecycleBase中,等着被触发
比如HostConfig就是一个监听Host的监听器

-在这里插入图片描述

其他所有的base都是继承自Lifecyclebase:
所有的容器都是LifecycleBase:
在这里插入图片描述

在这里插入图片描述


由于是重新开了线程来找的所以我们需要从这个线程被添加的地方重新入手:

一直往上找,最后可以看到是由于我们通过命令行的Main方法来启动的:
在这里插入图片描述

getServer().start();
本质是执行StandardServer的start()方法,而这个方法是来自分类中实现的,自身并没有实现 实现在 org.apache.catalina.util.LifecycleBase#start中,但是又会回到子类的实现 org.apache.catalina.core.StandardServer#startInternal;

    @Override
   protected void startInternal() throws LifecycleException {

       fireLifecycleEvent(CONFIGURE_START_EVENT, null);
       setState(LifecycleState.STARTING);

       globalNamingResources.start();

       // Start our defined Services
       synchronized (servicesLock) {
           for (Service service : services) {
               service.start();
           }
       }
   }


可以看到 Server的Internal方法最后会去调用Service的start方法.

Service本质上也是org.apache.catalina.core.StandardService实现也是继承自LifecycleBase,自身也没有start方法覆盖,所有又调到父类中去了
同理父类中又调子类的startInternal方法
在这里插入图片描述
然后在服务类中又调用StandardEngine的start方法,同理在父类的start中继续调用org.apache.catalina.core.StandardEngine#initInternal 内部实现方法
这里要注意在Engine中是么有自己实现的而是调用自己的父类实现
在这里插入图片描述

这个类的父类有相关实现,父类间接是继承自刚刚说的LifecycleBase.

在这个类中org.apache.catalina.core.ContainerBase#startInternal
将所有的子控件start


本文链接: http://www.dtmao.cc/news_show_200390.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?