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

[经验分享] tomcat源码分析之Observer模式以及应用加载--Lifecycle

[复制链接]

尚未签到

发表于 2017-2-4 10:05:42 | 显示全部楼层 |阅读模式
  研究过tomcat源码的朋友们可能都发现了,tomcat中几个主要的component都实现了Lifecycle接口,并且在
  start的时候通常都会publish一些事件。在这个过程中tomcat是通过Observer模式来实现相关功能的。下面以StandardHost为例来说明。
  StandardHost是StandardContext(也就是部署在tomcat下面的一个个应用)的上级Container.Host是在Digester server.xml文件的时候生成的。但是,在digester的时候,并没有standardcontext的相关配置。那么,StandardContext是如何加载的呢?
  下面就来研究一下standardhost的源码:
  先来看init源码:

public void init() {
if( initialized ) return;
initialized=true;
// already registered.
if( getParent() == null ) {
try {
// Register with the Engine
ObjectName serviceName=new ObjectName(domain +
":type=Engine");
HostConfig deployer = new HostConfig();
addLifecycleListener(deployer);               
if( mserver.isRegistered( serviceName )) {
if(log.isDebugEnabled())
log.debug("Registering "+ serviceName +" with the Engine");
mserver.invoke( serviceName, "addChild",
new Object[] { this },
new String[] { "org.apache.catalina.Container" } );
}
} catch( Exception ex ) {
log.error("Host registering failed!",ex);
}
}
if( oname==null ) {
// not registered in JMX yet - standalone mode
try {
StandardEngine engine=(StandardEngine)parent;
domain=engine.getName();
if(log.isDebugEnabled())
log.debug( "Register host " + getName() + " with domain "+ domain );
oname=new ObjectName(domain + ":type=Host,host=" +
this.getName());
controller = oname;
Registry.getRegistry(null, null)
.registerComponent(this, oname, null);
} catch( Throwable t ) {
log.error("Host registering failed!", t );
}
}
}

  StandardHost本身是一个container(ContainerBase),从以上代码可以看出,它在初始化的时候注册了一个LifecycleListener:HostConfig. 不同于一般的Observer模式的地方是,standard并不直接拥有listeners,而是通过拥有一个工具类-LifecycleSupport来维护与listeners的关系。这样就使得代码看起来很干净。已经注册了Observer,那么在哪里触发事件呢?事件触发是在container启动的时候(其实观察tomcat6中的重要组件,比如standardserver,standardservice以及container如standardengine,standardhost,standardcontext,他们在start的时候都会发布这么几个事件:beforestartevent,startevent,afterstartevent). 于是在standardhost start的时候,触发事件,listeners作出响应,hostconfig的响应代码如下:

public void lifecycleEvent(LifecycleEvent event) {
if (event.getType().equals(Lifecycle.PERIODIC_EVENT))
check();
// Identify the host we are associated with
try {
host = (Host) event.getLifecycle();
if (host instanceof StandardHost) {
setDeployXML(((StandardHost) host).isDeployXML());
setUnpackWARs(((StandardHost) host).isUnpackWARs());
setXmlNamespaceAware(((StandardHost) host).getXmlNamespaceAware());
setXmlValidation(((StandardHost) host).getXmlValidation());
}
} catch (ClassCastException e) {
log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e);
return;
}
// Process the event that has occurred
if (event.getType().equals(Lifecycle.START_EVENT))
start();
else if (event.getType().equals(Lifecycle.STOP_EVENT))
stop();
}
  可以看出,如果触发的事件是START_EVENT,那么hostconfig调用自己的start方法。而正是在
  start方法里面,调用deployApps来生成standardContext.
  至此,不仅了解了tomcat中Lifecycle的Observer模式,而且了解了tomcat加载应用的流程。可谓一举两得。

运维网声明 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-337266-1-1.html 上篇帖子: Java 开发环境配置(JRe JDk MyEclipse Tomcat) 下篇帖子: J2EE安全策略:为tomcat页面设置访问权限[转]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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