
天下武功唯简不破, 如何骑在驴身上然后牵着驴往前走?
热启动:
JFinal Undertow 热加载, 就属于热启动,改了代码自动加载生效。一般都需要自定义ClassLoader来实现。
冷启动:
手工点停止,开始按钮强行停止服务。从而触发默认ClassLoader重新加载。
除了热启动和冷启动其实还可以实现一种自启动 -> 自动调用冷启动, 来达到不用手工冷启的效果。
PS:这种不适合线上环境, 仅适用于本地开发环境, 提升开发体验和效率, 就像默认线上会关闭热加载一样.
/**
* 全程避免使用 super.loadClass(...),以免被 parent 加载到不该加载的类
*/
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
/**
* 生产环境所有类文件统一加载方式,不再进行额外判断
* 生产环境避免使用 parent 加载,是为了能从额外添加的
* config 目上录下面加载配置文件
*/
if (! UndertowConfig.isDevMode()) {启动时把server 实例存起来
public static void main(String[] args) {
// 启动Server全局共享
UndertowUtil.server = UndertowServer.create(AppConfig.class).addSystemClassPrefix("com.eova.common.utils.util.UndertowUtil");
UndertowUtil.server.addHotSwapClassPrefix("org.beetl.").addHotSwapClassPrefix("com.eova.").start();
}所以就可以实现静态的全局共享, 在启动时把UndertowServer对象存起来, 就可以随时拿出来按在地上磨 擦(restart).
public class UndertowUtil {
/**
* 当前启动服务全局共享
*/
public static UndertowServer server = null;
/**
* 重启当前服务
*/
public static void restart() {
if (server != null) {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.err.println("Undetow Server Restarting ......");
Thread.sleep(500);// 延迟500ms, 避免Web来不及返回信息
server.restart();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
return;
}
}关键的梗
.addSystemClassPrefix("com.eova.common.utils.util.UndertowUtil")判断是否为系统类文件,系统类文件无条件使用 parent 类加载器加载
如果不添加为SystemClass 就会导致静态变量最终为null, 两个时空的类加载 静态变量分别初始化 无法共享
可以通过输出HashCode 发现不一样, 说明存在于不同的内存中.
ClassLoader 和 JVM 可以说是最Java最底层的东西了, 水很深, 需要慢慢修-炼-内-功.
https://blog.csdn.net/kdsde/article/details/81537024
在需求未到来之前就能预知并实现功能,极端考验设计者的智慧
点赞