日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Java基于自定義類加載器實現熱部署過程解析

瀏覽:26日期:2022-09-04 15:12:59

熱部署:

熱部署就是在不重啟應用的情況下,當類的定義即字節碼文件修改后,能夠替換該Class創建的對象。一般情況下,類的加載都是由系統自帶的類加載器完成,且對于同一個全限定名的java類,只能被加載一次,而且無法被卸載。可以使用自定義的 ClassLoader 替換系統的加載器,創建一個新的 ClassLoader,再用它加載 Class,得到的 Class 對象就是新的(因為不是同一個類加載器),再用該 Class 對象創建一個實例,從而實現動態更新。如:修改 JSP 文件即生效,就是利用自定義的 ClassLoader 實現的。

還需要創建一個守護線程,不斷地檢查class文件是否被修改過,通過判斷文件的上次修改時間實現。

演示:

原來的程序:

Java基于自定義類加載器實現熱部署過程解析

修改后重新編譯:

Java基于自定義類加載器實現熱部署過程解析

代碼:

package Dynamic; import java.io.*;import java.nio.file.Files;import java.nio.file.Path;import java.util.concurrent.TimeUnit; public class ClassLoadStudy { public static void main(String[] args) throws Exception { HotDeploy hot = new HotDeploy('Dynamic.Task'); hot.monitor(); while (true) { TimeUnit.SECONDS.sleep(2); hot.getTask().run(); } }} // 熱部署 class HotDeploy { private static volatile Runnable instance; private final String FILE_NAME; private final String CLASS_NAME; public HotDeploy(String name) { CLASS_NAME = name; // 類的完全限定名 name = name.replaceAll('.', '/') + '.class'; FILE_NAME = (getClass().getResource('/') + name).substring(6); // 判斷class文件修改時間使用,substring(6)去掉開頭的file:/ } // 獲取一個任務 public Runnable getTask() { if (instance == null) { // 雙重檢查鎖,單例,線程安全 synchronized (HotDeploy.class) {if (instance == null) { try { instance = createTask(); } catch (Exception e) { e.printStackTrace(); }} } } return instance; } // 創建一個任務,重新加載 class 文件 private Runnable createTask() { try { Class clazz = MyClassLoader.getLoader().loadClass(CLASS_NAME); if (clazz != null)return (Runnable)clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } // 監視器,監視class文件是否被修改過,如果是的話,則重新加載 public void monitor() throws IOException { Thread t = new Thread(()->{ try {long lastModified = Files.getLastModifiedTime(Path.of(FILE_NAME)).toMillis();while(true) { Thread.sleep(500); long now = Files.getLastModifiedTime(Path.of(FILE_NAME)).toMillis(); if(now != lastModified) { // 如果class文件被修改過了 lastModified = now; instance = createTask(); // 重新加載 }} } catch (InterruptedException | IOException e) {e.printStackTrace(); } }); t.setDaemon(true); // 守護線程 t.start(); }} // 自定義的類加載器class MyClassLoader extends ClassLoader { @Override public Class<?> findClass(String name) throws ClassNotFoundException { try { String fileName = '/' + name.replaceAll('.', '/') + '.class'; InputStream is = getClass().getResourceAsStream(fileName); byte[] b = is.readAllBytes(); return defineClass(name, b, 0, b.length); } catch (IOException e) { throw new ClassNotFoundException(name); } } public static MyClassLoader getLoader() { return new MyClassLoader(); }}

遇到的坑:

剛開始自定義類加載器時,重寫的是 loadClass(String name) 方法,但不斷地報錯,后來明白了,因為 Task 類實現了 Java.lang.Runnable 接口,且重寫 loadClass 方法破壞了雙親委派機制,導致了自定義的類加載器去加載 java.lang.Runnable,但被Java安全機制禁止了所以會報錯。defineClass調用preDefineClass,preDefineClass 會檢查包名,如果以java開頭,就會拋出異常,因為讓用戶自定義的類加載器來加載Java自帶的類庫會引起混亂。

于是又重寫findClass 方法,但還是不行,findClass方法總是得不到執行,因為編譯好的類是在 classpath 下的,而自定義的 ClassLoader 的父加載器是 AppClassLoader,由于雙親委派機制,類就會被 Application ClassLoader來加載了。因此自定義的 findClass 方法就不會被執行。解決方法是,向構造器 ClassLoader(ClassLoader parent) 傳入null,或傳入 getSystemClassLoader().getParent()。

還有就是路徑問題:

path不以 / 開頭時,默認是從此類所在的包下取資源;path 以 / 開頭時,則是從ClassPath根下獲取; URL getClass.getResource(String path) InputStream getClass().getResourceAsStream(String path) getResource('') 返回當前類所在的包的路徑 getResource('/') 返回當前的 classpath 根據路徑 path 不能以 / 開始,path 是從 classpath 根開始算的, 因為classloader 不是用戶自定義的類,所以沒有相對路徑的配置文件可以獲取,所以默認都是從哪個classpath 路徑下讀取,自然就沒有必要以 / 開頭了 。 URL Class.getClassLoader().getResource(String path) InputStream Class.getClassLoader().getResourceAsStream(String path)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久精品亚洲一区二区| 久久久久久黄| 九一精品国产| 蜜桃成人av| 模特精品在线| 亚洲一二av| 国产欧美一区二区三区米奇| 国产精品激情电影| 日本免费一区二区三区四区| 不卡中文字幕| 日韩在线麻豆| 精品视频一区二区三区在线观看 | 国产欧美一区二区色老头| 欧美精品观看| 国产夫妻在线| 国产婷婷精品| 国产精品三级| 久久视频国产| 日韩二区在线观看| 国产一区二区三区视频在线| 亚洲午夜视频| 国产精品视频一区视频二区| 成人在线网站| 日韩在线黄色| 老牛影视精品| 中文字幕av一区二区三区四区| 欧美国产另类| 一本一本久久| 国产成人精品一区二区免费看京| 日韩视频免费| 欧美激情久久久久久久久久久| 欧美一区三区| 国产精品免费99久久久| 精品一区免费| 国产欧美亚洲一区| 久久国产成人午夜av影院宅| 亚州精品视频| 日韩天堂在线| 欧美日本一区| 国产麻豆综合| 亚洲一区资源| 国产精品一区二区av日韩在线| 欧美日韩激情| 久久久久久婷| 视频一区中文字幕精品| 欧美有码在线| 亚洲免费观看| 精品日本视频| 婷婷五月色综合香五月| 天堂√8在线中文| 无码日韩精品一区二区免费| 欧产日产国产精品视频| 欧美日韩亚洲一区在线观看| 午夜国产欧美理论在线播放 | 福利一区和二区| 日韩精品一区二区三区中文字幕| 亚洲精品一级二级| 国产精品qvod| 日韩高清中文字幕一区| 国产亚洲综合精品| 国产99久久| 精品国产乱码久久久| 午夜久久av| 好吊一区二区三区| 亚洲va中文在线播放免费| 国产精品亚洲综合色区韩国| 国产视频欧美| 亚洲va在线| 亚洲综合电影| 精品欧美视频| 国产精品sss在线观看av| 日本成人在线不卡视频| 在线免费观看亚洲| 一区二区自拍| 不卡av一区二区| 美女网站一区| 久久精品在线| 成人在线网站| 婷婷成人在线| 激情欧美一区二区三区| 欧美日韩精品免费观看视欧美高清免费大片 | 男女男精品网站| 欧美日韩国产免费观看视频| 成人自拍av| 日韩av片子| 国产白浆在线免费观看| 高清不卡一区| 国产v综合v| 日韩大片在线| 日韩欧美三级| 欧美日韩中文字幕一区二区三区| 成人免费电影网址| 久久黄色影院| 精品一区欧美| 久久午夜精品| 亚洲男人在线| 日韩av午夜在线观看| 久久激情五月婷婷| 国产精品麻豆成人av电影艾秋| 亚洲a级精品| 国产日韩欧美高清免费| 免费精品一区| 热三久草你在线| 精品捆绑调教一区二区三区| 91精品在线观看国产| 国产一区亚洲| 久久福利毛片| 日本在线视频一区二区| 97精品国产99久久久久久免费| 欧美日韩亚洲三区| 国产一区二区三区久久| 四虎4545www国产精品 | 日韩av自拍| 99久久久国产精品美女| 亚洲综合不卡| 日韩激情啪啪| 国产在线不卡一区二区三区| 丝袜av一区| 性欧美长视频| 国产精品毛片久久久| 人在线成免费视频| 欧美日韩少妇| 国产日韩精品视频一区二区三区| 福利一区二区三区视频在线观看| 久久国产亚洲精品| 综合激情一区| 久久精品99久久久| 日韩精品91| 美女精品在线| 久久一区欧美| 欧美精选一区二区三区| 欧美午夜网站| 久久久精品网| 日韩一区二区三区精品视频第3页| 国产精品九九| 91成人超碰| 国产精品va| 欧美另类专区| 欧美激情福利| 国产精品普通话对白| 久久精品系列| 亚洲欧美日本日韩| 欧美aaaaaa午夜精品| 六月丁香综合| 成人影视亚洲图片在线| 亚洲三级视频| 欧美日韩在线观看首页| 亚洲专区视频| 亚洲成av在线| 欧美另类中文字幕 | 精品无人区麻豆乱码久久久| 亚洲一区二区三区高清| 精品三级av在线导航| 鲁大师成人一区二区三区| 国产精品.xx视频.xxtv| 日韩午夜av| 神马午夜在线视频| 欧美一区在线观看视频| 国产主播一区| 久久影院一区二区三区| 久久国产精品毛片| 日韩久久电影| 69堂精品视频在线播放| 欧美在线资源| 中文字幕在线看片| 久久99免费视频| 巨乳诱惑日韩免费av| 久久久久久久久99精品大| 精品中文字幕一区二区三区| 免费看日韩精品| 四虎884aa成人精品最新| 久久中文字幕一区二区| 亚洲精选成人| 亚洲精品一二三区区别| 在线精品亚洲欧美日韩国产| 久久av网址| 日本精品另类| 石原莉奈在线亚洲三区| 久久婷婷一区| 92国产精品| 精品久久在线| 国产精品一区二区三区四区在线观看| 日韩精品一二三| 在线一区免费观看| 久久久国产亚洲精品| 欧美少妇精品| 国产成人精品一区二区免费看京| 国产精品对白| 欧美三区不卡| 日本aⅴ亚洲精品中文乱码| 日韩影院在线观看| 妖精视频成人观看www| 激情综合网站| 亚洲调教视频在线观看| 99久久www免费| 亚洲不卡系列| 欧美香蕉视频| 亚洲成人va| 欧美日韩一区二区综合| 亚洲www啪成人一区二区|