您好,登錄后才能下訂單哦!
這篇文章主要講解了“java類加載器與類的熱替換怎么實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“java類加載器與類的熱替換怎么實現”吧!
任何一個使用到的Class,都需要被classLoader加載到JVM中,這個加載的過程,又分為
defineClass
loadClass
resolveClass
即根據提供的不同形式的class文件的內容,轉化成一個Class,對其進行加載,鏈接。
而所謂的hotswap,就是使用新的代碼替換掉已經加載的這個Class中的內容。
我們這里使用Javassist來模擬類似的效果,通過動態的修改class內某個方法的內容,來實現熱替換的效果。
基本步驟:
先定義一個接口,包含一個方法,該方法內的內容在后面用于熱替換
定義一個接口的實現
在Servlet內接收頁面上傳入的參數,頁面上的參數內容,則是具體上面接口定義方法及方法對應的方法體內容
在接收到參數后,根據參數內容,使用Javassist進行熱替換的操作。
基本Javassist的代碼大概是下面的樣子:
ITemp test = new Temp(); // 聲明一個接口
ClassPool pool = new ClassPool(true);
private ITemp hotswap(String str) {
String methodBody = null;
try {
//添加到classpath
pool.insertClassPath(new ClassClassPath(ITemp.class));
String className = "ITemp_" + UUID.randomUUID();
CtClass clazz = pool.makeClass(className);
clazz.setInterfaces(new CtClass[]{pool.get("com.xxxx.ITemp")});
methodBody = str;
clazz.addMethod(CtMethod.make(methodBody, clazz));
ITemp fun = (ITemp) clazz.toClass().newInstance();
calculatorClass.writeFile("d:/temp");
return fun;
} catch(Exception e) {
}
在用的過程中,接收到參數后,把hotswap方法返回的實例再指給test這個實例。然后test內對應方法的執行已經改成在頁面上傳入的邏輯。
原理
上面的是怎么樣實現的呢?
其實,上面的替換,實質上,是重新生成了一個ITemp這個接口的實現類,然后我們在頁面上定義的,是這個實現類的方法中的內容。然后我們的替換,是把一個實現類的引用改成另一個。
在更新Server中service的引用,指向新的實現,舊的會在引用請求執行完成后會被釋放。
另外一個
這時,一定有同學提起JDK默認支持的 Agent,這種基于JVMTI的實現。但是,這里需要注意的是,此時使用的是Agent,如果使用其pre_main,那么支持的是Class的 defineClass執行前,對其進行所謂的增強或者是織入,類似于OpenJPA的Enhance和AJP的weave。
這種相當于是把class內容在讀到內容之后修改了一下,然后傳給classLoader進行defineClass。
而JVMTI在JDK1.6之后,支持的另外一種形式,是在應用已經部署啟動之后,要進行類的改變的,使用的是agent_main方法,此時,需要對class進行retransform。像Java里一些常用的Profiler工具使用的就是這種,attach到已經啟動的Java進程,對其進行retransform,例如Btrace。
這里的transform會調用Instrumention的RedefineClass,本質上是修改類的定義。我們以Btrace為例,來看他在背后做了什么。
我的Trace腳本內容如下:
@BTrace(unsafe=true)
public class TracingScript {
@OnMethod(clazz="com.xxx.WorkFun", method="myPrint")
public void sc() {
println("===========");
}
}
對于要監控的類WorkFun,我們看到,Btrace監控后,會類內新增一個方法$btrace$TracingScript$sc()
該方法就所做的就是我們在Trace腳本里定義的內容,比如上面,我們會在對應java方法執行時打印一行等號,其對應的方法jvm指令如下:
而這個方法是如何和我們自己要監控的方法聯系起來的呢?就是在我們的監控方法第一行,增加了對于trace方法的調用。
感謝各位的閱讀,以上就是“java類加載器與類的熱替換怎么實現”的內容了,經過本文的學習后,相信大家對java類加載器與類的熱替換怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。