设为首页 收藏本站
查看: 625|回复: 0

[经验分享] 浅析Tomcat之HostConfig的应用部署

[复制链接]

尚未签到

发表于 2017-2-1 11:25:57 | 显示全部楼层 |阅读模式
HostConfig主要承担虚拟主机启动是部署应用的作用.其中可以分解为3个类型的应用.在它的实现中主要分解为3个方法和内部类来解决.部署应用也就是动态在代码中生成Host的子容器Context.也就是一个app和一个Context对应.
我们知道deployApps这个方法把应用的部署分解到deployDescriptors,deployWARs,deployDirectories中.分别对应了3中形式的应用.那么我们先看下deployDescriptors

/**
* Deploy XML context descriptors.
*/
protected void deployDescriptors(File configBase, String[] files) {
if (files == null)
return;
ExecutorService es = host.getStartStopExecutor();
List<Future<?>> results = new ArrayList<Future<?>>();
for (int i = 0; i < files.length; i++) {
File contextXml = new File(configBase, files);
if (files.toLowerCase(Locale.ENGLISH).endsWith(".xml")) {
ContextName cn = new ContextName(files);
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);
}
}
}

   这个方法主要部署XML配置描述的应用.我们可以看到它和核心内容就是用ThreadPoolExecutor的submit方法来执行DeployDescriptor任务.也就是提交一个返回值的任务用于执行.其中的result.get()是处理任务中的异常.DeployDescriptor的run方法调用的是HostConfig的deployDescriptor方法.另外两种的应用部署方式跟这个是类似的.也是使用线程池来执行部署.

protected void deployDescriptor(ContextName cn, File contextXml) {
DeployedApplication deployedApp = new DeployedApplication(cn.getName());
// Assume this is a configuration descriptor and deploy it
if(log.isInfoEnabled()) {
log.info(sm.getString("hostConfig.deployDescriptor",
contextXml.getAbsolutePath()));
}
Context context = null;
boolean isExternalWar = false;
boolean isExternal = false;
File expandedDocBase = null;
try {
synchronized (digester) {
try {
context = (Context) digester.parse(contextXml);
} catch (Exception e) {
log.error(sm.getString(
"hostConfig.deployDescriptor.error",
contextXml.getAbsolutePath()));
context = new FailedContext();
} finally {
digester.reset();
}
}
Class<?> clazz = Class.forName(host.getConfigClass());
LifecycleListener listener =
(LifecycleListener) clazz.newInstance();
context.addLifecycleListener(listener);
context.setConfigFile(contextXml.toURI().toURL());
context.setName(cn.getName());
context.setPath(cn.getPath());
context.setWebappVersion(cn.getVersion());
// Add the associated docBase to the redeployed list if it's a WAR
if (context.getDocBase() != null) {
File docBase = new File(context.getDocBase());
if (!docBase.isAbsolute()) {
docBase = new File(appBase(), context.getDocBase());
}
// If external docBase, register .xml as redeploy first
if (!docBase.getCanonicalPath().startsWith(
appBase().getAbsolutePath() + File.separator)) {
isExternal = true;
deployedApp.redeployResources.put(
contextXml.getAbsolutePath(),
Long.valueOf(contextXml.lastModified()));
deployedApp.redeployResources.put(docBase.getAbsolutePath(),
Long.valueOf(docBase.lastModified()));
if (docBase.getAbsolutePath().toLowerCase(Locale.ENGLISH).endsWith(".war")) {
isExternalWar = true;
}
} else {
log.warn(sm.getString("hostConfig.deployDescriptor.localDocBaseSpecified",
docBase));
// Ignore specified docBase
context.setDocBase(null);
}
}
host.addChild(context);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
log.error(sm.getString("hostConfig.deployDescriptor.error",
contextXml.getAbsolutePath()), t);
} finally {
// Get paths for WAR and expanded WAR in appBase
.......
}
if (context != null && host.findChild(context.getName()) != null) {
deployed.put(context.getName(), deployedApp);
}
}

   上述就是在es.submit(new DeployDescriptor(this, cn, contextXml))中的线程中执行的方法.其大意主要也就是把解析出来的app转换成Tomcat中的Context做为Host的子容器.在另外的2个类型的部署应用方法deployWAR,deployDirectory所实现的也是类似的.只不过DeployDescriptor和deployWAR主要解析的是ApplicationContextXml也就是META-INF/context.xml,而deployDirectory主要解析的是ApplicationWebXml也就是/WEB-INF/web.xml其余大体上的流程是一致的.
 
 
首发于泛泛之辈 - http://www.lihongkun.com/archives/152

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-336080-1-1.html 上篇帖子: tomcat之是否编译JSP的条件 下篇帖子: Tomcat中Java垃圾收集调优
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表