黑马程序员_高新技术三(类加载器)

----------- android培训java培训、java博客、java学习型技术博客、期待与您交流! --------------


本章主要的知识点总结:1类加载器概念、系统默认三个类加载器树形结构,类加载器的委托加载机制

                                        2、掌握如何自定义类加载器的方法。

                                        3、了解Tomcat中Servlet是如何加载的

                                        



一.类加载器简介

1、java虚拟机中可以安装多个类加载器,系统默认三个主要的类加载器,每个加载器负责加载特定位置的类。系统默认的三个类加载器之间的父子关系:BootStrap(爷)------ExtClassLoader(父)-----AppClassLoader(子)注意:类加载器也是java类,但是这些加载器类本身又由谁来加载呢?显然必须有第一个类加载器不是java类,这个加载器就是BootStrap,BootStrp是JVM里的第一个类加载器,它不是java类,不需要被加载,它是嵌套在JVM内核里的, 它是用C++写的二进制代码。其他两个加载器都是java类。

  (1)类加载器及其作用:
  字节码的原始信息存放在硬盘上的classpath指定的目录下,java程序用到某个类,虚拟机要先
  将该类的字节码加载到内存里,进行处理后得到的就是字节码。实现这个过程的机制就是类加载器,
  其作用就是加载类。

  (2)java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定
  位置的类:

    BootStrap,ExtClassLoader,AppClassLoader


  (3)类加载器的树形结构
   BootStrap   -------> JRE/lib/rt.jar
     |
   ExtClassLoader -----> JRE/lib/ext/*.jar
     |
   AppClassLoader -----> CLASSPATH指定的所有jar或目录
     |
  MyClassLoader     --> 自己指定的特殊目录

 

二.类加载器的委托加载机制

  (1)当java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
     首先当前线程的类加载器去加载线程中的第一个类。
     如果类A中引用了类B,java虚拟机将使用加载类A的类装载器来加载类B。
    还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。  
 (2)每个类加载器加载类时,又先委托给其上级类加载器。 当所有父类包括BootTrap类加载器没有加载到类,回到发起者加载器,还加载不了,则抛出ClassNoFoundException,
(3ClassLoader类(java.lang)
     类加载器是负责加载类的对象。ClassLoader 类是一个抽象类。
    每个 Class 对象都包含一个对定义它的 ClassLoader 的引用。

    数组类的 Class 对象不是由类加载器创建的,而是由 Java 运行时根据需要自动创建

常用方法:

  protected  Class<?> findClass(String name) 
   使用指定的二进制名称查找类。 
   ClassLoader getParent() 
      返回委托的父类加载器。 
   static ClassLoader getSystemClassLoader() 
      返回委托的系统类加载器。 
   Class<?> loadClass(String name) 

      使用指定的二进制名称来加载类。 


四.自定义类加载器
(1)定义原理:
  ClassLoader中的loadClass()方法是保证委托机制流程的方法,故只能继承,不能复写,查找类要用到
  的findClass需要复写,将得到的class文件的内容转成字节码的方法是defineClass(),也不需要复写。
    编写一个自定义的ClassLoader 对文件进行加密,解密。
public class MyClassLoader extends ClassLoader {  
  1.                public MyClassLoader(String classDir){  
  2.         this.classDir = classDir;  
  3.     }  
  4.     public static void main(String[] args)throws Exception {      
  5.         // 从主函数的参数中获取源Class文件,和目标地址  
  6.         String srcPath = args[0];  
  7.         String desDir = args[1];  
  8.         FileInputStream fis = new FileInputStream(srcPath);    
  9.         String desFileName = srcPath.substring(srcPath.lastIndexOf("\\")+1);  
  10.         String desPath = desDir+"\\"+desFileName;   
  11.         FileOutputStream fos = new FileOutputStream(desPath); 
  12.         cypher(fis,fos);  
  13.         fis.close();  
  14.         fos.close();  
  15.     }  
  16.     //加密 解密方法  
  17.     public static void cypher(InputStream ips ,OutputStream ops)throws Exception{  
  18.         int b = 0;  
  19.         while((b = ips.read())!= -1)  
  20.         {  
  21.             ops.write(b^0xff);  
  22.         }  
  23.     }  
  24.     private String classDir;  
  25.     @Override  
  26. //  重写findClass方法,loadClass不需要覆盖。  
  27.     protected Class<> findClass(String name) 
  28. throws ClassNotFoundException {    
  29.         String classFileName =   
  30.             classDir+"\\"+name.substring(name.lastIndexOf("."))+1 +".class";  
  31.           
  32.         try {  
  33.             FileInputStream fis = new FileInputStream(classFileName);  
  34.             ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  35.             cypher(fis,bos);  
  36.             byte[] bytes = bos.toByteArray();  
  37.             //把字节数组通过defineClass方法返回Class文件,  
  38.             return defineClass(bytes, 0, bytes.length);  
  39.         } catch (Exception e) {  
  40.             e.printStackTrace();  
  41.         } finally{fis.close; bos.close()} 
  42.         return super.findClass(name);  
  43.     }  
  44. }  

   五.Tomcat及一个类加载器的高级问题分析


Servlet是由Tomcat自己的类加载器加载的。
他的目录关系是 
ExtClassLoader
AppClassLoader
StandardClassLoader
WebappClassLoader
 在eclipse中的演示步骤:
 1.创建web项目itcastweb, 创建web中的类Servlet(web中的类是特殊的类,其父类是Servlet,故可直接创建Servlet)
 2.配置服务器
  选择web工程-->点击Project Deployments-->Add-->Server:Tomcat 6.x -->Finish-->OK
  (配置完后在目录apache-tomcat-6.0\webapps下就有itcastweb文件夹)
 3启动Tomcat,即双击startup.bat
 4.在浏览器中访问Tomcat服务器
  http://localhost:8080/itcastweb/servlet/MyServlet(这是项目内的路径)
  (查看内容:itcastweb-->webRoot-->WEB-INF-->web.xml-->source)
      结果打印到了后台
 5.重载Tomcat,则会在浏览器显示Tomcat自己的类加载器:WebappClassLoader
 6.将MyServlet.java打成jar包输出到JDK下,重启Tomcat
  MyServlet.java-->右键-->Export-->java--JAR file-->Next-->Next-->Finish
  (输出的JDK版本要和Tomcat配置的JDK一致,可查看Tomcat的配置,即将startup.bat放在
   编辑器中打开:set JAVA_HOME=c:\java\JDK6.0)
 7.在浏览器中再次查看,报错:没找到HttpServlet.
  (这是因为,这时的发起者加载器是ExtClassLoader,而HttpServlet不在Ext目录下)
 8.将HttpServlet的jar包也放在Ext目录下。 重启Tomcat(即将JVM重启)
  HttpServlet是Tomcat提供的,在apache-tomcat-6.0\lib\servlet-api.jar,复制到JDK6.0\jre\lib\ext下。
 9.再在浏览器中访问, 此时显示的加载器便是ExtClassLoader了。



 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值