Tomcat 热部署实现方式源码分析总结

  研究了一下tomcat的类的热部署的源码实现,总结沉淀一下。Tomat实现热部署主要有两种机制:

(1) 一种是类似于Servlet这种类的热部署即在WEB-INF/class目录下的类:实现方式可以概括为在容器启动的时候起一条后台线程,定时的检测类文件的时间戳变化,如果类的时间戳变掉了,则调用容器的reload的方法,将类重新载入。

那么具体的分析一下:

tomcat用来加载servlet的类加载器是WebappClassLoader,但热部署的逻辑不是在这个类加载器里,而是封装在了外围的WebappLoader里面(WebappClassLoader 是WebappLoader的成员变量)。WebappLoader作为一个加载器,其实现了Loader接口,loader接口中定义了两个和热部署密切相关的方法即modified方法和backgroundProcess方法。Modified方法关联了载入器中资源的变化情况,而backgroundProcess则定义了后台线程定时扫描时具体要执行的逻辑。

Tomcat的启动具体可以分解为各级容器的启动(即:Engine,host,context 注意不包含Wrapper,Wrapper是在具体请求的时候初始化的)和连接器(默认两种连接器Http,ajp)的启动,另外当然还做了一些配置文件的解析这个不多说。容器启动根据tomcat的生命周期启动方式是调用容器的start方法,start方法调用了具体的startInternal方法来做一些初始化的工作,其中就包括检测类文件变化的后台线程的初始化及启动,具体看一下ContainerBase的StartInternal方法:


在这个方法的最后一行,调用了threadStart()方法,这个方法就是在启动后台线程,看一下方法体:


由这段代码可知,这个方法启动了一条线程,其中ContainerBackgroundProcessor一定是实现了Runnable接口的具体的后台线程执行的逻辑,那就继续看:


至此就看到了后台线程的定义的真实面目,其中有个变量backgroundProcessDelay 这个变量的值会影响这条线程的睡眠时间,那也就说后台线程定时执行的时间是可配置的。最后一行调用了processChildren方法,这个方法又是具体的执行逻辑,那么断点调试看下是如何完成了类的重载的。

ProcessChildren方法定义如下:


这里调用了容器的backgroundProcess方法。Debug信息如下:


这个方法调用了载入器的WebappLoader的backgroundProcess方法。

      WebappLoader的backgroundProcess方法如下:


       标注处有两个校验项,一个是reloadable一个是modified方法。这个reloadable就是是否执行热部署的开关,这个可以在$CATALINA_HOME/conf/context.xml 当中配置一下,这个开关默认是不打开的。我修改了一下配置项如下:

       Context.xml:


添加reloadable=true后,即可完成context容器的类的热部署。修改之后调试信息如下:


再来看一下第二个校验方法modified方法。这个modified方法会调用WebappClassLoader的Modified来判断文件是否被修改。如果两个校验项都为真的话,就会调用容器的reload方法(这里说的容器是Context容器)

       Context容器的这个reload方法定义如下:


这个reload方法实现的还是很简单粗暴的,就是讲整个Context容器重启了一下,先stop,然后再start.(容器都重启了,那容器课件范围的类自然会被重新加载了)

       以上就是tomcat7.x实现WEB-INF/classes当中类热部署的大体流程。除了WEB-INF/classes当中的类之外,还有一种特殊的类是默认热部署的,这个就是JSP。

       (2)为了实现JSP的加载部署,tomcat实现了另一个加载器即org.apache.jasper.servlet.JasperLoader.JSP属于一次消费品,每次访问都会重新加载(网上说的,这个源代码下次再研究下,在这先记录下)

       (3)在读源码的时候身边研究了下$CATALINA_HOME/conf/web.xml,这个配置文件是tomcat内置的配置文件,主要配置了两个Servlet. 具体的配置如下:


      

DefaultServlet是要作用是为静态资源请求提供服务,包括图片、html等。还有一个用来解析JSP的servlet:

JspServlet完成了Servlet的编译,以及请求的处理。下面那个配置项<load-on-startup>的意思是当配置项的数值大于0时(数值越大被加载的优先级越低)就在容器启动时候就加载这个Servlet 执行这个Servlet的init方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值