上一篇文章,我们讲了一下Tomcat的reload,怎么评价这个reload呢,以手枪为例:

reload和上述的手枪的状态是一样的,手枪的基本框架是不变的,我将弹夹拿下来,把里面的子弹重新上膛,然后重新装上弹夹;
手枪我没有进行拆卸,但是这个状态我可以更快速的让手枪能够得到发射;
再看看重部署是啥,可以类比国产59式手枪,每一次拆卸:

重部署类似于这种拆卸,不仅仅是弹夹了;
扯的有点远了,但我们现在应该能明白Tomcat的Context.reload和重部署之间的区别了吧,Tomcat的Context.reload是在Context的后台线程中运行,当reloadable属性设置为true(也就是配置Loader子组件的时候)才会执行,该功能只针对于应用Context,不同的应用又不同的配置;
但是,重部署的功能都定义在HostConfig类中,其默认就是开启的,随着Host容器组件的lifecycle的period_event事件进行周期性的进行检测,它检测的是Tomcat所有部署的apps,上述二者的作用对象是不一样的;
看看代码:

check方法其实就是重部署的主要流程。
HostConfig是虚拟主机的管理器,它能监控在当前虚拟主机下的所有应用的状态,和应用中资源的情况,这两个属性抽象为:

1.redeployResources
redeployResources是当web应用部署时候,将应用监测的资源包和部署描述文件context.xml,作为监测对象进行添加的;

以目录部署的话,直接往Tomcat的Webapps目录下扔一个目录,其文件目录就是需要监视的对象,
以压缩包进行部署的话,redeployResources不但加上解压之后的文件目录,还需要加上原有的部署的压缩包,
除此之外,context.xml作为部署描述文件,该文件是需要监视的,
对于部署压缩包而言,其包中的MATA-INF/context.xml会自动拷贝到catalinabase/conf/localhost/xxx/context.xml中,该文件就是需要监视的对象,
对于目录直接部署的话,如果你在当前应用目录的MATA-INF/context.xml有存在的话,该context.xml就是需要监视的,
上述的context.xml是应用自己的配置,对于全局的context.xml.default,catalinaBase/conf/context.xml也是被监视的;
总而言之,redeployResources是被检测的对象,该对象一旦发生变化,checkResource方法就开始进行工作,如果监测的部署包没了,那么直接undeploy,如果发生了变化,发起重部署的流程,先卸载再部署:

从上述的流程来看,当部署描述文件context.xml没有修改的前提下,仅仅是应用包的变化(context.xml已经存在),就会调用context.reload;
而如果context.xml发生变化了,也就是当前应用的配置需要变化,需要重新读取这些配置,那么就不是context.reload的事了;
回应前面的主题,context.reload你可以理解为弹夹重新上膛,而上述的基于部署描述文件发生变化的重部署,是需要枪械进行分解的,比如说,你现在的手枪是59式,那么很可能你重部署完事之后,就变成勃朗宁手枪;
2.reloadResources
context.reload在Context级别,通过配置loader子元素的reloadable属性进行开启,默认如果没有配置是不开的;
其次,我们需要明确的一点是,loader子元素的reloadable属性的检测触发机制是WebappClassloader中的已经load的资源的发生一些变化,而如果WebappClassloader没有load过的资源发生变化,是不会触发context.reload的;
而对于HostConfig中的reloadResources的资源检测的范围,要不比Context级别中的loader子元素的reloadable配置要全的多;
可以看看HostConfig的addWatchResources:

这些资源是通过Context.findWatchResources()能拿到当前应用中所有需要watch的监视资源。
其对应的就是watchResources;
默认的context.xml中的就是web.xml....

在自己的Context.xml中可以定义自己业务逻辑的监视单元:

总结:
1.Context级别可以配置Loader元素,该元素中有一个reloadable属性可以配置(默认为false),如果配置了,那么当前WebappClassLoader加载过的资源,如果发生变化,就会触发我们上一节讲的Context.reload;
2.HostConfig级别的redeployResources是标识当前应用是否重部署的资源列表,该资源一般为context.xml,应用war包,应用目录等,粒度较粗,如果该资源发生变化,那么应用将得到重部署;
3.HostConfig级别还有一个reloadResources,该属性对应的是watchResources配置,默认是web.xml和Web-inf/classes,Web-inf/lib中的资源,比第一点要全并且默认开启,而这个配置对业务应用也开放,应用也可以自己定义一些watchResources,当这些watchResources发生变化的时候,也会进行Context.reload;
上面的三点,第二点是重部署,第一点和第三点较类似,都触发context.reload,但是二者监测的资源不同;




