您好,登錄后才能下訂單哦!
這篇文章主要講解了“JVM中classloader的作用是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“JVM中classloader的作用是什么”吧!
public Class<?> loadClass(String name) throws ClassNotFoundException 通過(guò)類(lèi)名發(fā)揮這個(gè)類(lèi)的Class實(shí)例
protected final Class<?> defineClass(byte[] b,int off,int len) 根據(jù)給定的字節(jié)碼流 b,off 和 len 參數(shù)表示實(shí)際的 class 信息在byte 數(shù)組中的位置和長(zhǎng)度,其中 byte 數(shù)組 b是 classloader 從外部獲取的
protected Class<?> findClass(String name)throws ClassNotFoundException 查看一個(gè)類(lèi)
protected final Class<?> findLoadedClass(String name)
BootStrap ClassLoader
Extension ClassLoader
AppClassLoader 啟動(dòng)類(lèi)加載器負(fù)責(zé)加載系統(tǒng)的核心類(lèi)(rt.jar的java類(lèi)),擴(kuò)展類(lèi)加載器加載 %JAVA_HOME/lib/ext/*.jar中的類(lèi),應(yīng)用類(lèi)加載器用于加載用戶(hù)類(lèi) (classpath),自定義類(lèi)加載器加載一些特殊路徑的類(lèi)(自定義classloader)
當(dāng)前 classloader 首先從自己已經(jīng)加載的類(lèi)中查詢(xún)是否此類(lèi)已經(jīng)加載,如果已經(jīng)加載了則直接返回原來(lái)已經(jīng)加載的類(lèi)
當(dāng)前 classloader 的緩存中沒(méi)有找到被加載的類(lèi)的時(shí)候,委托父類(lèi)加載器去加載,父類(lèi)加載器采用同樣的策略,首先查下自己的緩存,然后委托父類(lèi)去加載,一直到 bootstrap classloader
當(dāng)所有的父類(lèi)加載器都沒(méi)有加載的時(shí)候,再由當(dāng)前的類(lèi)加載器加載,并將其放入自己的緩存中,下次請(qǐng)求的時(shí)候直接返回
一直循環(huán)重復(fù)
各個(gè)類(lèi)加載器的基礎(chǔ)類(lèi)統(tǒng)一
jar -cvf test.jar HelloLoader.class 把class打包成jar
例子:在 ext 路徑下放一個(gè)自己 jar 包并加載
package com.mousycoder.server; public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }
idea 通過(guò) structs->artifacts->jar 然后 build-> build artifacts->build 生成 helloworld.jar 放到 /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext
package com.mousycoder.mycode.thinking_in_jvm; import java.lang.reflect.Method; /** * @version 1.0 * @author: mousycoder * @date: 2019-09-06 10:35 */ public class ExtClassLoader { public static void main(String[] args) throws ClassNotFoundException { System.out.println(System.getProperty("java.ext.dirs")); Class<?> helloClass = Class.forName("com.mousycoder.server.HelloWorld"); System.out.println(helloClass.getClassLoader()); } }
輸出
/Users/mousycoder/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java sun.misc.Launcher$ExtClassLoader@610455d6
可以看出是 ExtClassLoader 加載 java.ext.dirs 目錄
package com.mousycoder.mycode.thinking_in_jvm; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; /** * @version 1.0 * @author: mousycoder * @date: 2019-09-06 11:13 */ public class MyClassLoader extends ClassLoader { private final static Path DEFAULT_CLASS_PATH = Paths.get("","/Users/mousycoder/My"); private final Path classDir; public MyClassLoader(){ super(); this.classDir = DEFAULT_CLASS_PATH; } public MyClassLoader(String classDir){ super(); this.classDir = Paths.get(classDir); } public MyClassLoader(String classDir, ClassLoader parent){ super(parent); this.classDir = Paths.get(classDir); } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { try { byte[] classBytes = this.readClassBytes(name); if (null == classBytes || 0 == classBytes.length){ throw new ClassNotFoundException("can not load the class" + name); } return this.defineClass(name,classBytes,0,classBytes.length); } catch (IOException e){ e.printStackTrace(); } return null; } private byte[] readClassBytes(String name) throws ClassNotFoundException, IOException { String classPath = name.replace(".","/"); Path classFullPath = classDir.resolve( "HelloWorld1.class"); if (!classFullPath.toFile().exists()){ throw new ClassNotFoundException("The class" + name + "mpt found"); } try (ByteArrayOutputStream baos = new ByteArrayOutputStream()){ Files.copy(classFullPath,baos); return baos.toByteArray(); } catch (IOException e){ throw new ClassNotFoundException("load the class " + name + "occur error",e); } } @Override public String toString() { return "My ClassLoader"; } } package com.mousycoder.mycode.thinking_in_jvm; /** * @version 1.0 * @author: mousycoder * @date: 2019-09-06 11:34 */ public class MyClassLoaderTest { public static void main(String[] args) throws ClassNotFoundException { MyClassLoader classLoader = new MyClassLoader(); Class<?> class1 = classLoader.loadClass("com.mousycoder.mycode.thinking_in_jvm.HelloWorld1"); System.out.println(class1.getClassLoader()); } } package com.mousycoder.mycode.thinking_in_jvm; /** * @version 1.0 * @author: mousycoder * @date: 2019-09-06 11:46 */ public class HelloWorld1 { public static void main(String[] args) { System.out.println("Hello world1 "); } }
把helloword1變成class放到/Users/mousycoder/My目錄下即可 輸出 My ClassLoader 代表 自定義類(lèi)加載器加載了該類(lèi)
打破雙親委托機(jī)制,讓上層父類(lèi)加載器可以使用子類(lèi)的加載器加載對(duì)象,比如Spi中的接口類(lèi)在系統(tǒng)加載器中,但是實(shí)現(xiàn)類(lèi)在應(yīng)用加載器中
保證每個(gè)應(yīng)用的類(lèi)庫(kù)獨(dú)立隔離(即使同限定名不同版本的)
保證相同類(lèi)庫(kù)相同版本的類(lèi)庫(kù)共享
保證容器自身的類(lèi)庫(kù)和程序獨(dú)立
bootstrap 引導(dǎo)類(lèi)加載器
system 系統(tǒng)類(lèi)加載器
應(yīng)用類(lèi)加載器 WEB-INF/classes
應(yīng)用類(lèi)加載器 WEB-INF/lib
common 類(lèi)加載器 CATALINA/lib
感謝各位的閱讀,以上就是“JVM中classloader的作用是什么”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)JVM中classloader的作用是什么這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。