javawebday69(类加载器 自定义 Tomcat类加载器)
2018-03-30 10:14
423 查看
类加载器 1、类加载器 把.class文件加载到JVM的方法区中,变成一个Class对象 2、得到类加载器 Class#getClassLoader() 3、类加载器的分类 都是片警。 引导:类库rt.jar 扩展:扩展jar包 系统:应用下的class,包含开发人员写的类,和第三方的jar包。classpath下的类 系统类加载器的上层领导:扩展 扩展类加载器的上传领导:引导 引导没上层,是BOSS 4、类加载器的委托机制 代码中出现了这么一行:new A(); 系统发现了自己加载的类,其中包含了new A();说明需要系统去加载A类 系统会给自己的领导打电话,让扩展去自己的地盘去加载A类 扩展会给自己的领导打电话,让引导去自己的地盘去加载A类 引导自己会去rt.jar中寻找A类 如果找到了,那么加载。然会返回A对应的Class对象给扩展,扩展也会把这个Class返回给系统,完成 如果没找到: 引导给扩展返回一个NULL,扩展会自己去自己的地盘,寻找A类 如果找到了,那么加载,返回A对应的Class对象给系统,结束 如果没找到 扩展返回一个null给系统了,系统去自己的地盘(应用程序下)加载A类 如果找到了,那么加载,然后返回这个Class,结束 如果没找到,抛出异常ClassNotFoundException 5、类的解析过程 class MyApp{//被系统加载 main(){ A a new A();//也由系统加载 String s = new String();//也由系统加载 } } 因为谁导致的加载就 谁就负责加载全部 class String{//引导 private Integer i;//直接引导加载 } Thread.getContextClassLoader()获取当前线程的类加载器 代理模式保证了JDK中的类一定是由类加载加载的,这样就不会出现多个版本的类,也是代理模式的好处 3、自定义类加载器 可以通过继承ClassLoader类来完成自定义类加载器,自定义类加载器的目的一般是为了加载网络上的类, class在网上传输经过加密,需要用自定义的类加载器来加载(自定义的类加载器需要做解密工作) ClassLoader加载类都是通过loadClass()方法来完成的,loadClass()工作流程 调用findLoadedClass()方法查看该类是否已经被加载过了,如果该类没有加载过,那么这个方法返回null 【在JVM的方法区中查看已加载过的类,即判断当前类是否已被加载过】 判断findLoadedClass()方法返回的是否为null,如果不是null,那么直接返回,可以避免同一个类被加载两次 如果findLoadedClass()返回的是null那么就启动代理模式(委托机制),即调用上级的loadClass(),获取上级的方法是getParent()如果上级还有上级,就一直往上 如果getParent().loadClass()返回的不是null,那么说明上级加载成功了,那么加载结果 如果上级返回的是null,就说明需要自己出手了,这时loadClass()方法会调用本类的findClass()方法来加载类 只需要重写ClassLoader的findClss()方法就可以覆盖代理模式 6、自定义类加载器 继承ClassLoader 重写findClass 类加载器没有继承关系 父类加载器-->上层加载器 类加载器都是引导类加载器加载的。因为都是类库的一部分 引导类加载器是JVM的一部分不需要别人加载。JVM出生时就带引导类加载器过来了。加载完类库就出现扩展和系统类加载器 然后就加载其他的 7、Tomcat的类加载器 Tomcat提供了两种类加载器 服务器类加载器:${CATALINA_HOME}\lib,tomcat服务器类加载器,负责加载这个下面的类 应用类加载器:${CONTEXT_HOME}\WEB-INFO\lib、${CONTEXT_HOME}\WEB-INFO\classes,应用类加载器,负责加载这两个路径下的类。 Tomcat可以使自己项目下的类优先被加载 引导 扩展 系统 特性: 服务器类加载器:先自己动手,然后再去委托 应用类加载器: 先自己动手,然后再去委托【比服务器优先级高,最好还是放在应用类】
public class Demo1 { @Test public void fun1(String name) throws ClassNotFoundException{ System.out.println("1"); System.out.println(name); } public static String fun2(String name) { System.out.println(name); return "a"; } }
public class FileSystemClassLoader extends ClassLoader { private String classpath;//每个类加载器都有自己的位置,这是自己的 public FileSystemClassLoader() { } public FileSystemClassLoader(String classpath) {//创建类加载器时为其指定负责的位置,它只会到这里去查找类 this.classpath = classpath; } @Override public Class<?> findClass(String name) throws ClassNotFoundException { try { byte[] datas = getClassData(name);//通过类名称找到.class文件,把文件加载到一个字节数组中 if(datas == null){//如果返回的字节数组为null,说明没有找到这个类,抛出异常 throw new ClassNotFoundException("类没有找到" + name); } //可以在这里对datas进行解密 return this.defineClass(name, datas, 0,datas.length);//可以把字节数组变成Class对象。defineClass()是ClassLoader的方法,作用是把字节数组变成Class对象 } catch (Exception e) { e.printStackTrace(); throw new ClassNotFoundException("类找不到:"+name); } } private byte[] getClassData(String name) throws IOException { name = name.replace(".", "\\") + ".class"; File classFile = new File(classpath,name); return FileUtils.readFileToByteArray(classFile); } }
public class Test01 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { ClassLoader loader = new FileSystemClassLoader("D:\\myeclipsework\\day09_01\\src\\"); Class clazz = loader.loadClass("my.demo1.Demo1"); Method method = clazz.getMethod("fun2", String.class); String result = (String) method.invoke(null, "abc"); System.out.println(result); } }
相关文章推荐
- tomcat类加载器的层次及加载路径
- 类的加载机制,反射,内省,类的加密和自定义加载器
- JVM 核心机制(类加载器、自定义文件系统类加载器、网络自定义类加载器
- Java类加载机制及自定义加载器
- 自定义类加载器加载自定义类:能否加载自定义的java.lang.xxxxxx
- 自定义下拉刷新上拉加载的帮助接口ScrollableHelper
- Android自定义webView头部进度加载效果
- 自定义加载器问题
- flex可自定义圆形加载进度条例子代码下载
- Android:图解classloader加载class的流程及自定义ClassLoader
- vuejs -- 如何使一个自定义函数在加载时自动执行
- 虚拟机类加载机制(2)——类加载器
- 自定义View模拟下载/加载动态progress
- 框架开发原理/类加载器加载配置文件
- 深入剖析Classloader(二)--根类加载器,扩展类加载器与系统类加载器
- 自定义缓冲加载界面
- 【类加载器的高级问题——改变servlet的类加载器】
- 自定义struts2的Dispatcher加载方式
- 类加载器(DexClassLoader)与插件化(动态加载)
- LayoutInflater和inflate()方法的用法 (自定义View中加载xml布局)