对于许多新手来说,WEB应用程序是如何部署的并不十分清楚。为了帮助大家解决这个问题,下面小编就详细讲解一下。需要的人可以从中学习,希望你能有所收获。
一个WEB应用程序,无论是解压缩的目录还是压缩的WAR文件,都可以部署到应用服务器。
从安装的网络应用程序到应用服务器的过程,我们称之为部署.
应用程序部署有多种形式:
静态:即应用程序服务器启动时服务器中存在的应用程序。
动态:也就是说,当应用服务器运行时,它动态地向应用服务器添加应用,以支持应用请求。
通过Tomcat的自动部署特性,可以在Tomcat中实现动态部署。
远程部署也可以通过Tomcat的Manager应用程序来实现。
今天我们先来看看Tomcat的自动部署原理。
整个主机配置中涉及许多类型的部署。
当自动部署时,我们的常规操作是直接将标准WAR应用程序放入
%Tomcat_HOME%/webapps
目录,后台线程会定期扫描,如果有需要部署的应用,会启动部署流程进行应用部署。对于背景线程,感兴趣的朋友可以阅读之前的文章:
Tomcat对过期的会话做了什么?
当后台线程发现我们的应用程序时,它将调用
在主机配置类中
DeployWar方法。
Tomcat支持带有context.xml的应用程序部署,提供xml配置格式等。所以方法中有很多逻辑来判断各种部署情况。
最终,一个Web应用会对应到一个StandardContext对象上,一个Web应用又会被部署到一个虚拟主机上。
核心逻辑是以下几行:
上课?clazz=class . for name(host . getconfigclass());
LifecycleListenerlistener=
(LifecycleListener)clazz . new instance();
context.addLifecycleListener(侦听器);
context . setname(cn . getname());
context . SetPath(cn . GetPath());
context . setwebappversion(cn . getversion());
context . setdocbase(cn . GetBasename()'。战争’);
host.addChild(上下文);设置上下文的属性后,将其添加到虚拟主机上的host.addchild(上下文)中。
在addChild的逻辑中,主要是启动这个应用程序。
//开始
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.xml
和default web.xml
的merge,以及解析应用中是否包含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); }
再然后,就是对于filter
和listener
等组件的启动了。这些组件的启动是根据前一个组件是否启动成功,再决定是否继续
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启动。可能某天面试时会有人问到,或者涉及到应用组件加载问题时,记的在这里看到过。
在组件等全部启动完毕后,整个应用部署就完成了。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/102824.html