编辑
2023-11-10
Tomcat源码学习
00
请注意,本文编写于 546 天前,最后修改于 546 天前,其中某些信息可能已经过时。

热加载的原理是开启一个后台线程,检查文件变化,变化就重新加载类。

java
// ContainerBackgroundProcessor实现Runnable接口,负责后台处理 protected class ContainerBackgroundProcessor implements Runnable { @Override // run方法是主处理逻辑 public void run() { // 定义变量保存可能出现的异常 Throwable t = null; // 定义变量保存线程意外死亡的日志信息 String unexpectedDeathMessage = sm.getString("containerBase.backgroundProcess.unexpectedThreadDeath", Thread.currentThread().getName()); try { // 循环处理,直到线程结束 while (!threadDone) { try { // 每隔一定时间睡眠 Thread.sleep(backgroundProcessorDelay * 1000L); } catch (InterruptedException e) { // 忽略中断异常 } if (!threadDone) { // 调用processChildren方法处理子容器 processChildren(ContainerBase.this); } } } catch (RuntimeException | Error e) { // 如果发生异常,保存到t变量并抛出 t = e; throw e; } finally { if (!threadDone) { // 线程意外死亡打印日志 log.error(unexpectedDeathMessage, t); } } } // 处理子容器 protected void processChildren(Container container) { // 保存当前类加载器 ClassLoader originalClassLoader = null; try { if (container instanceof Context) { // Context实例获取类加载器 Loader loader = ((Context) container).getLoader(); // Loader可能为null,忽略 if (loader == null) { return; } // 使用Context的类加载器 originalClassLoader = ((Context) container).bind(false, null); } // 处理当前容器 container.backgroundProcess(); // 获取子容器 Container[] children = container.findChildren(); for (Container child : children) { if (child.getBackgroundProcessorDelay() <= 0) { // 处理子容器 processChildren(child); } } } catch (Throwable t) { // 处理异常 ExceptionUtils.handleThrowable(t); log.error(sm.getString("containerBase.backgroundProcess.error"), t); } finally { if (container instanceof Context) { // 恢复类加载器 ((Context) container).unbind(false, originalClassLoader); } } } }
java
public void backgroundProcess() { //1. 执行容器中 Cluster 组件的周期性任务 Cluster cluster = getClusterInternal(); if (cluster != null) { cluster.backgroundProcess(); } //2. 执行容器中 Realm 组件的周期性任务 Realm realm = getRealmInternal(); if (realm != null) { realm.backgroundProcess(); } //3. 执行容器中 Valve 组件的周期性任务 Valve current = pipeline.getFirst(); while (current != null) { current.backgroundProcess(); current = current.getNext(); } //4. 触发容器的 " 周期事件 ",Host 容器的监听器 HostConfig 就靠它来调用 fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null); }

本文作者:yowayimono

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!