JVM核心机制_深入类加载器JAVA220-223
来源:互联网 发布:哈佛计算机编程课程 编辑:程序博客网 时间:2024/05/22 04:58
来源:http://www.bjsxt.com/
一、S02E220_01JVM核心机制_深入类加载器、层次结构(三种类加载器)、代理加载模式、双亲委派机制
类加载器的作用
java.lang.ClassLoader类介绍
类加载器的层次结构(树状结构)
类加载器的代理模式
java.lang.ClassLoader类API详细介绍
System.out.println(ClassLoader.getSystemClassLoader());System.out.println(ClassLoader.getSystemClassLoader().getParent());System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());System.out.println(System.getProperty("java.class.path"));
二、S02E221_01JVM核心机制_深入类加载器、自定义文件系统类加载器、网络自定义类加载器
package com.test.classloader;/** * 测试自定义的FileSystemClassLoader */public class Demo02 { public static void main(String[] args) throws Exception { FileSystemClassLoader loader = new FileSystemClassLoader("g:/java/test"); FileSystemClassLoader loader2 = new FileSystemClassLoader("g:/java/test"); Class<?> c = loader.loadClass("com.test.helloworld.HelloWorld"); Class<?> c2 = loader.loadClass("com.test.helloworld.HelloWorld"); Class<?> c3 = loader2.loadClass("com.test.helloworld.HelloWorld"); Class<?> c4 = loader2.loadClass("java.lang.String"); Class<?> c5 = loader2.loadClass("com.test.classloader.Demo02"); System.out.println(c.hashCode()); System.out.println(c2.hashCode());//同一加载器加载同一个类的Class对象相同 System.out.println(c3.hashCode());//不同加载器加载同一个类,JVM认为也是不相同的类 System.out.println(c4.hashCode()); System.out.println(c4.getClassLoader());//引导类加载器 System.out.println(c3.getClassLoader());//自定义的类加载器 System.out.println(c5.getClassLoader());//系统默认的类加载器 }}
package com.test.classloader;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;/** * 自定义文件系统类加载器 */public class FileSystemClassLoader extends ClassLoader { //com.test.helloworld -->> g:/java/test com/test/HelloWorld.class private String rootDir; public FileSystemClassLoader(String rootDir){ this.rootDir = rootDir; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { Class<?> c = findLoadedClass(name); //应该要先查询有没有加载过这个类。如果已经加载,则直接返回加载好的类。如果没有,则加载新的类 if(null!=c){ return c; }else{ ClassLoader parent = this.getParent(); try { c = parent.loadClass(name);//委派给父类加载 } catch (Exception e) { //e.printStackTrace(); } if(null!=c){ return c; }else{ byte[] classData = getClassData(name); if(null==classData){ throw new ClassNotFoundException(); }else { c = defineClass(name, classData, 0, classData.length); } } } return c; } private byte[] getClassData(String className){ String path = rootDir + "/" + className.replace(".", "/") + ".class"; //Apache工具:IOUtils,可以使用它将流中的数据转成字节数组。此处不使用 InputStream is = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { is = new FileInputStream(path); byte[] buffer = new byte[1024]; int temp = 0; while( (temp=is.read(buffer)) != -1 ){ baos.write(buffer,0,temp); } return baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); return null; } finally { if(null!=is){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if(null!=baos){ try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
控制台输出
658586165858612625313833121026nullcom.test.classloader.FileSystemClassLoader@25154fsun.misc.Launcher$AppClassLoader@1d16e93
自定义网络类加载器
package com.test.classloader;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.URL;/** * 自定义网络类加载器 */public class NetClassLoader extends ClassLoader { //com.test.helloworld -->> www.test.com/java/test/ com/test/HelloWorld.class private String rootUrl; public NetClassLoader(String rootUrl){ this.rootUrl = rootUrl; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { Class<?> c = findLoadedClass(name); //应该要先查询有没有加载过这个类。如果已经加载,则直接返回加载好的类。如果没有,则加载新的类 if(null!=c){ return c; }else{ ClassLoader parent = this.getParent(); try { c = parent.loadClass(name);//委派给父类加载 } catch (Exception e) { //e.printStackTrace(); } if(null!=c){ return c; }else{ byte[] classData = getClassData(name); if(null==classData){ throw new ClassNotFoundException(); }else { c = defineClass(name, classData, 0, classData.length); } } } return c; } private byte[] getClassData(String className){ String path = rootUrl + "/" + className.replace(".", "/") + ".class"; //Apache工具:IOUtils,可以使用它将流中的数据转成字节数组。此处不使用 InputStream is = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { URL url = new URL(path); is = url.openStream(); byte[] buffer = new byte[1024]; int temp = 0; while( (temp=is.read(buffer)) != -1 ){ baos.write(buffer,0,temp); } return baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); return null; } finally { if(null!=is){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if(null!=baos){ try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
三、S02E222_01JVM核心机制_深入类加载器、自定义加密解密类加载器
package com.test.classloader;/** * 测试简单加密解密(取反)操作 */public class Demo03 { public static void main(String[] args) throws Exception { //测试取反操作// int a = 3;//00000011// System.out.println(Integer.toBinaryString(a^0xff)); //加密后的class文件,正常的类加载器无法加载,报ClassFormatError// FileSystemClassLoader loader = new FileSystemClassLoader("g:/java/test");// Class<?> c = loader.loadClass("com.test.helloworld.temp.HelloWorld");// System.out.println(c); DecrptClassLoader loader = new DecrptClassLoader("g:/java/test/temp"); Class<?> c = loader.loadClass("HelloWorld"); System.out.println(c); }}
package com.test.classloader;import java.io.FileInputStream;import java.io.FileOutputStream;/** * 加密工具类 */public class EncrptUtil { public static void main(String[] args) { //测试时,原class文件中,相关的类不要打包 encrpt("g:/java/test/HelloWorld.class", "g:/java/test/temp/HelloWorld.class"); } public static void encrpt(String src,String dest){ FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(src); fos = new FileOutputStream(dest); int temp = -1; while((temp=fis.read())!=-1){ fos.write(temp^0xff);//取反操作,相当于加密 } } catch (Exception e) { e.printStackTrace(); } finally { try { if (fis != null) { fis.close(); } } catch (Exception e) { e.printStackTrace(); } try { if (fos != null) { fos.close(); } } catch (Exception e) { e.printStackTrace(); } } }}
package com.test.classloader;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;/** * 加载文件系统中加密后的class字节码的类加载器(解密加载) */public class DecrptClassLoader extends ClassLoader { private String rootDir; public DecrptClassLoader(String rootDir){ this.rootDir = rootDir; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { Class<?> c = findLoadedClass(name); //应该要先查询有没有加载过这个类。如果已经加载,则直接返回加载好的类。如果没有,则加载新的类 if(null!=c){ return c; }else{ ClassLoader parent = this.getParent(); try { c = parent.loadClass(name);//委派给父类加载 } catch (Exception e) { //e.printStackTrace(); } if(null!=c){ return c; }else{ byte[] classData = getClassData(name); if(null==classData){ throw new ClassNotFoundException(); }else { c = defineClass(name, classData, 0, classData.length); } } } return c; } private byte[] getClassData(String className){ String path = rootDir + "/" + className.replace(".", "/") + ".class"; //Apache工具:IOUtils,可以使用它将流中的数据转成字节数组。此处不使用 InputStream is = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { is = new FileInputStream(path); int temp = -1; while((temp=is.read())!=-1){ baos.write(temp^0xff);//取反操作,相当于解密 } return baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); return null; } finally { if(null!=is){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if(null!=baos){ try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
四、S02E223_01JVM核心机制_线程上下文类加载器、web服务器类加载机制、OSGI技术模块开发原理介绍
线程上下文类加载器
package com.test.classloader;/** * 线程上下文类加载器的测试 */public class Demo05 { public static void main(String[] args) throws Exception { ClassLoader loader = Demo05.class.getClassLoader(); System.out.println(loader); ClassLoader loader2 = Thread.currentThread().getContextClassLoader(); System.out.println(loader2); Thread.currentThread().setContextClassLoader(new FileSystemClassLoader("g:/java/test")); System.out.println(Thread.currentThread().getContextClassLoader()); Class<Demo01> c = (Class<Demo01>) Thread.currentThread().getContextClassLoader().loadClass("com.test.classloader.Demo01"); System.out.println(c); //写的时候,FileSystemClassLoader采用双亲委派机制,所以是AppClassLoader。这个可以按自己的方式修改,这里只是测试,不改了。 System.out.println(c.getClassLoader()); }}
TOMCAT服务器的类加载机制
OSGI原理介绍
0 0
- JVM核心机制_深入类加载器JAVA220-223
- JVM核心机制_深入类加载器JAVA220-223
- JVM核心机制_类加载全过程JAVA218-219
- 深入JVM类加载机制
- 222_尚学堂_高淇_java300集最全视频教程_JVM核心机制_深入类加载器_自定加密解密类加载器
- JVM核心机制,类加载全过程
- 【深入理解JVM】:类加载机制
- 《深入理解JVM》--JVM类加载机制总结
- 深入JVM虚拟机(六) JVM类加载机制
- 深入JVM类加载器
- JVM类加载器机制
- 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题
- 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题
- 深入JVM之类加载、类加载器、双亲委派机制与常见问题
- 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题
- 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题
- 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题
- 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题
- alibaba druid数据源配置参考
- Git常用命令解说
- 安卓程序中RadioGroup的使用
- awk去重
- 数组实用类Arrays和枚举类型Enum
- JVM核心机制_深入类加载器JAVA220-223
- leetcode_061 Rotate List
- LeetCode 27. Remove Element
- 解决s:iterator 中嵌套s:radio的传值方法
- 并查集 hdu3038 How Many Answers Are Wrong
- Oozie安装配置简介
- 笔试题(2016.4.7)
- 对象存储
- WTL for Visual Studio 2012 配置详解