java很強大,特別是加載系統,看到好多人在背空洞的概念,可沒有實踐過,我就表演下
0. 原材料:
先建幾個java文件
打開cmd,切換到想要的工作盤符,比如d: 按回車鍵,然後cd到工作目錄
然後新建目錄md code,然後cd code,然後在建子目錄md classloader,最後進入到子目錄下
開始新建三個java文件:PrintService.java,PrintServiceImpl.java,ServiceTest.java
cd .>PrintService.java
cd .>PrintServiceImpl.java
cd .>ServiceTest.java
public interface PrintService {
void print(String msg);
}
public class PrintServiceImpl implements PrintService{
@Override
public void print(String msg) {
System.out.println("Jar Hello : " + msg);
}
}
public class ServiceTest{
public static void main(String[] args) {
PrintServiceImpl printService = new PrintServiceImpl();
printService.print("world jar");
}
}
然後切換到主目錄下,編譯java源文件
//編譯
javac code\classloader\*.java
//運行測試
java code.classloader.ServiceTest
效果圖:
似乎可以了,但最後都是達成jar包的
記得先建個配置文件manifest.mf
Main-Class: code.classloader.ServiceTest
執行jar命令
jar -cvfm serviceTest.jar manifest.mf code\classloader\*.class
然後執行jar
java -jar serviceTest.jar
1. 用開發工具eclipse,也可其他工具,新建項目
先建包名code.classloader, 然後分別建和上面一樣的三個同包同名的java文件
然後運行代碼看效果是哪個加載器:
還記得原料中生成的jar包嗎,好,把這個jar包放到jdk的加載路徑下
在次執行上面中的代碼,
不是希望的結果,期望輸出world not jar,可實際上不是,調用的父加載器裏同名類,還記得以前寫的類加載系統和雙親委派機制怎麼回事嗎 https://blog.csdn.net/dong19891210/article/details/106010293 加載環節,務必搞懂加載器,在JVM的世界裏是很重要的
那有沒有辦法繞過系統自帶的加載器執行輸出:world not jar, 特別是碼農們開發的程序都不是系統級的程序,是應用型程序,要想控制,就得自定義加載器,當然了有的人一輩子也用不到這高級功能,純碎是小概率事件。
答案是可以的,那就是自定義加載器,這對框架(比如tomcat)來說也很重要,熱更新功能,版本替換
以前聽人說同名同類在JVM只會有一份,有前置條件吧,甚至連私有屬性都可以訪問
小結: 類加載系統,再加上SPI,會讓系統更加靈活擴展!!!這也是目標
附:
這種約定 META-INF/services/無法改變了,直接在源碼裏寫死了,而且類也是final類
不過也可以參考:Spring Factories Loader或Dubbo的玩法
沒有對錯,編程其實就是定規矩、定標準,或許我們學的並不是技術,而是人家定的規矩,特別是java生態和pring生態 上萬頁的英文文檔,類似於現實中的協會、商會(豫商、微商、蘇商等)!!!
參考:
0. What is a Java ClassLoader? http://net-informations.com/java/cjava/classloader.htm
1. How classloader works int java (要翻牆) https://javarevisited.blogspot.com/2012/12/how-classloader-works-in-java.html?m=1
2.JarURLConnection https://docs.oracle.com/javase/8/docs/api/java/net/JarURLConnection.html
3. JarInputStream in Java https://www.concretepage.com/java/example-of-jarinputstream-in-java
4. JAVA CLASSLOADER – PART 5 – COMPLETE REFERENCE
https://analyzejava.wordpress.com/2014/09/25/java-classloader-part-5-complete-reference/
5. Sandboxing plugins in Java
https://blog.jayway.com/2014/06/13/sandboxing-plugins-in-java/
6. Extensions to the Class Loader https://docstore.mik.ua/orelly/java-ent/security/ch03_05.htm
7. ClassLoader理解及使用
https://juejin.im/post/5dce44d16fb9a0200f05362f
8. 自定義ClassLoader實現隔離運行多版本jar包的方式
http://kentt.top/2017/06/14/classLoader-jar/
9. Create Extensible Applications using Java ServiceLoader https://www.logicbig.com/tutorials/core-java-tutorial/java-se-api/service-loader.html
10. Dubbo可擴展機制實戰 http://dubbo.apache.org/zh-cn/blog/introduction-to-dubbo-spi.html
11. Super Charge the Module Aware Service Loader in Java 11 https://www.infoq.com/articles/java11-aware-service-module/