2026/5/24 18:51:37
网站建设
项目流程
中国美食网站模板免费下载,注册深圳公司新政策,wordpress登录菜单,wordpress不好文章目录Classloader的继承性。Classloader的隔离性。简单的plugin classloader自定义classloaderClassloader的继承性。
第一级叫做bootstrap classloader,加载JDK自带的类#xff0c;也就是${JAVA_HOME}/lib下的类。 第二级叫做extern classloader,加载${JAVA_HOME}/lib/ex…文章目录Classloader的继承性。Classloader的隔离性。简单的plugin classloader自定义classloaderClassloader的继承性。第一级叫做bootstrap classloader,加载JDK自带的类也就是${JAVA_HOME}/lib下的类。第二级叫做extern classloader,加载${JAVA_HOME}/lib/ext下的类。第三级叫做system classloader加载第三方的类就是classpath里其他的类。第四级及更高级叫做plugin classloader,是用户自己写的classloader或者new出来的URLClassLoader,加载classpath以外的类。在tomcat容器中每个应用里的WEB-INF/lib和WEB-INF/classes就是通过tomcat自定义的classloader去加载的。Classloader的隔离性。父级不能调用子级的类。比如extern classloader里加载的class不能调用system classloader加载的类会抛class not found异常.同一级不同classloader加载的类不能互相调用。比如有两个plugin classloader, loader A 与loader B。loader A加载的类class A不能调用loader B加载的类 class B.无法获取bootstrap Classloader的实例。System.out.println(String.class.getClassLoader());这个输出结果是null总而言之只能child加载的类调用parent加载的类。兄弟及各种远房亲戚不能互相调用。简单的plugin classloader直接使用jdk自带的url classloader就可以加载任意jar包里的类了。比如以下代码finalURLurlnewURL(file:///C:/Users/Ryan/IdeaProjects/learn/classloader/heap-1.0.jar);finalURLClassLoaderclassLoadernewURLClassLoader(newURL[]{url});finalClass?heapClassclassLoader.loadClass(net.cloudsun.head.SmallHeap);finalConstructor?constructorheapClass.getConstructor();finalObjectoconstructor.newInstance();finalMethodaddheapClass.getMethod(add,java.lang.Comparable.class);for(inti0;i10;i){add.invoke(o,-i);}System.out.println(o);自定义classloader当不能提供url时比如jar包不在磁盘里也不在http服务器上或者jar包是加密的。只能自己写classloader进行类的加载。自己写classloader最终必须继承Classloader类。因为这个类有个保护型且final的defineClass方法传入类的字节码也就是byte[]就可以加载一个类。也就是说class的来源是byte[]。比如publicclassJarClassLoaderextendsClassLoader{OverridepublicClass?loadClass(Stringname)throwsClassNotFoundException{// 从jar包里取byte数组try{JarFilejarFilenewJarFile(heap-1.0.jar);finalbyte[]bytesJarUtils.getByte(jarFile,name);if(bytesnull){returnsuper.loadClass(name);}returnsuper.defineClass(name,bytes,0,bytes.length);}catch(IOExceptione){e.printStackTrace();returnnull;}}}上述代码的JarUtils是一个自己写的工具类。publicstaticbyte[]getByte(JarFilejarFile,StringclassName){finalStringentryclassName.replace(.,/).class;finalJarEntryjarEntryjarFile.getJarEntry(entry);if(jarEntrynull){returnnull;}try(finalInputStreaminputStreamjarFile.getInputStream(jarEntry)){returnIOUtils.toByteArray(inputStream);}catch(IOExceptione){e.printStackTrace();returnnull;}}当然这个classloader写得并不规范。因为规范的classloader首先要调用parent classloader去加载类如果parent加载失败再自己加载而且加载的class必须缓存起来。因为从字节码加载class的开销是非常巨大的。当然前三级JDK自带的的classloader都会在loadClass方法里去检查class是否已经加载。所以只要每级class loader优先调用parent classloader就可以自动实现class的缓存。