HotSwapClassLoader类加载器何时开始加载类

com.jfinal.server.undertow.hotswap.HotSwapClassLoader.loadClass(String, boolean)代码如下

image.png

但是我翻遍jfinal的代码也没有找到HotSwapClassLoader.loadClass在哪里调用,HotSwapClassLoader何时成为了系统的类加载器?

在UndertowServer.doStart()配置了HotSwapWatcher

com.jfinal.server.undertow.UndertowServer.doStart()

image.png

HotSwapWatcher是一个独立的线程,检测class文件的变化,当class文件有变化时调用undertowServer.restart();重启服务

com.jfinal.server.undertow.hotswap.HotSwapWatcher.doRun()如下

image.png

在UndertowServer.restart()调用了

doStop();
config.replaceClassLoader();
doStart();

com.jfinal.server.undertow.UndertowServer.restart()如下

image.png

调用了config.replaceClassLoader();就替换了java的类加载器了吗?

config.replaceClassLoader()实际调用的是getClassLoaderKit().replaceClassLoader();

com.jfinal.server.undertow.UndertowConfig.replaceClassLoader()

image.png

但是replaceClassLoader仅仅是实例化HotSwapClassLoader,并没有使用加载class

com.jfinal.server.undertow.hotswap.ClassLoaderKit.replaceClassLoader()

image.png

然后没有找到HotSwapClassLoader.loadClass在哪里调用,HotSwapClassLoader何时成为了系统的类加载器?

之只找到了下面这一次调用,难道这一次调用之后,之后加载所有的类都会换成HotSwapClassLoader吗?

调用栈如下

com.jfinal.server.undertow.UndertowServer.start()

com.jfinal.server.undertow.UndertowServer.doStart()

com.jfinal.server.undertow.UndertowServer.init()

com.jfinal.server.undertow.UndertowServer.configJFinalFilter()

com.jfinal.server.undertow.UndertowServer.getJFinalFilter()

image.png

为什么Action也会使用HotSwapClassLoader加载呢?是在哪里配置的

image.png

image.png

评论区

李通

2021-06-22 00:05

@JFinal 我不是分享,我是反馈一个问题,我不知道HotSwapClassLoader如何和jfinal的controller关联上的

杜福忠

2021-06-22 10:13

UndertowServer里面有个方法:
private Class<? extends Filter> getJFinalFilter() {
try {
return (Class<? extends Filter>)config.getClassLoader().loadClass("com.jfinal.core.JFinalFilter");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
其中 config.getClassLoader().loadClass 就是调用的HotSwapClassLoader的loadClass
然后JFinalFilter里面又会初始化各个类init方法servlet的知识点了,里面的jfinal.init等等代码,得追着读了

杜福忠

2021-06-22 10:24

UndertowServer 》
doStart() 》
init() 》
configJFinalFilter() 》
Servlets.filter("jfinal", getJFinalFilter()) 》
config.getClassLoader().loadClass("com.jfinal.core.JFinalFilter") 》
.addInitParam("configClass", config.getJFinalConfig()) 》
public JFinalFilter(JFinalConfig jfinalConfig) 》
。。。servlet 》》
public void init(FilterConfig filterConfig) 》
jfinal.init(jfinalConfig, filterConfig.getServletContext()); 》
this.servletContext = servletContext;
this.contextPath = servletContext.getContextPath();

initPathKit();

Config.configJFinal(jfinalConfig); // start plugin, init log factory and init engine in this method
constants = Config.getConstants();

initActionMapping();
initHandler();
initRender();
initOreillyCos();
initTokenManager();
不扒了。大致就这

李通

2021-06-22 12:22

已经找打答案
JFinalFilter是使用HotSwapClassLoader类加载器加载
JFinalFilter类中的对象也会使用JFinalFilter绑定的HotSwapClassLoader类加载器加载例如
protected static final JFinal jfinal = JFinal.me();
上面的对象使用final会使用HotSwapClassLoader类加载器加载
下面这行代码加载新的类时也会使用HotSwapClassLoader加载,因为jfinal的类加载器是HotSwapClassLoader
jfinal.init(jfinalConfig, filterConfig.getServletContext());