温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

WEB应用是怎么被部署的

发布时间:2021-11-18 17:12:40 来源:亿速云 阅读:204 作者:柒染 栏目:大数据

WEB应用是怎么被部署的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

一个WEB应用,无论是解压后的目录,还是一个压缩的WAR文件,都支持部署到应用服务器中。

一个WEB应用安装到应用服务器的过程,我们称为部署

部署应用的形式又分多种:

  • 静态的:即应用服务器启动时就存在在Server中的应用。

  • 动态的:即应用服务器运行时动态的把应用添加应用服务器中,支持应用的请求。

            动态部署的实现在Tomcat中可以通过其自动部署特性来完成。

            也可以通过Tomcat的Manager应用来实现远程部署。

我们今天先来看一下Tomcat的自动部署实现原理。

整个HostConfig中涉及到多种类型的部署

自动部署的时候,我们常规操作是直接把一个标准WAR应用放到

%Tomcat_HOME%/webapps

目录下,而后台线程会定时扫描,发现有需要部署的应用,就会启动部署流程进行应用部署。对于后台线程,感兴趣的朋友可以看前面的文章: 对于过期的session,Tomcat做了什么?
后台线程发现了我们的应用后,会调用到 HostConfig类中的 deployWar方法。

由于Tomcat支持以context.xml这种提供xml配置格式的应用部署等,所以方法内有大量判断各类部署情况的逻辑。

最终,一个Web应用会对应到一个StandardContext对象上,一个Web应用又会被部署到一个虚拟主机上。
最核心的逻辑是下面这几行:

Class<?> clazz = Class.forName(host.getConfigClass());
            LifecycleListener listener =
                (LifecycleListener) clazz.newInstance();
            context.addLifecycleListener(listener);

            context.setName(cn.getName());
            context.setPath(cn.getPath());
            context.setWebappVersion(cn.getVersion());
            context.setDocBase(cn.getBaseName() + ".war");
            host.addChild(context);

在设置完Context的属性后,将其添加到虚拟主机上⇒ host.addChild(context)
在·addChild·的逻辑中,主要是把这个应用启动起来

        // Start child
        if ((getState().isAvailable() ||
                LifecycleState.STARTING_PREP.equals(getState())) &&
                startChildren) {
            try {
                child.start();
            } catch (LifecycleException e) {
                log.error("ContainerBase.addChild: start: ", e);
                throw new IllegalStateException
                    ("ContainerBase.addChild: start: " + e);
            }
        }

此处,启动内会处理许多事情,像Webapp的ClassLoader设置是否使用双亲委托,web.xmldefault web.xmlmerge,以及解析应用中是否包含web-fragement.xml,将多项配置合并后,这项工作是在ContextConfig类内完成的。
解析完web.xml后,会生成一个Webxml对象,需要根据具体的应用配置信息,初始化我们的组件了,例如Filter,Listener等,
例如下面的逻辑

private void configureContext(WebXml webxml) {
        for (FilterDef filter : webxml.getFilters().values()) {
            if (filter.getAsyncSupported() == null) {
                filter.setAsyncSupported("false");
            }
            context.addFilterDef(filter);
        }
        for (FilterMap filterMap : webxml.getFilterMappings()) {
            context.addFilterMap(filterMap);
        }
        context.setJspConfigDescriptor(webxml.getJspConfigDescriptor());
        for (String listener : webxml.getListeners()) {
            context.addApplicationListener(listener);
        }
for (ServletDef servlet : webxml.getServlets().values()) {
            Wrapper wrapper = context.createWrapper();

    wrapper.setOverridable(servlet.isOverridable());
   context.addChild(wrapper);
}

}

整个解析出的Servlet组件,又会被做为Context的子组件添加到应用中。
在解析完Servlet等组件后,会再根据配置设置Session的超时时间,SessionCookie的名称等。对这一部分,可以看前面的文章:深入Tomcat源码分析Session到底是个啥!
一切都OK后,设置应用的配置状态

// Make our application available if no problems were encountered
        if (ok) {
            context.setConfigured(true);
        } else {
            log.error(sm.getString("contextConfig.unavailable"));
            context.setConfigured(false);
        }

再然后,就是对于filterlistener等组件的启动了。这些组件的启动是根据前一个组件是否启动成功,再决定是否继续

if (!getConfigured()) {
                log.error( "Error getConfigured");
                ok = false;
            }

            // Configure and call application event listeners
            if (ok) {
                if (!listenerStart()) {
                    log.error( "Error listenerStart");
                    ok = false;
                }

根据Servlet规范进行的容器实现,都是先进行listener的启动,再进行filter启动。可能某天面试时会有人问到,或者涉及到应用组件加载问题时,记的在这里看到过。

在组件等全部启动完毕后,整个应用部署就完成了。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

web
AI