Java ClassLoader

转载 2012年03月21日 15:11:42
 1. 从一个简单小实验开始:

(1) Eclipse下建一简单Java project,写一个简单程序,如下:

Java代码 复制代码 收藏代码
  1. package com.javaeye.loader;   
  2.   
  3. public class URLClassLoaderTest {   
  4.     public void show() {   
  5.         System.out.println("I am running...");   
  6.     }   
  7. }  

 

(2) 到项目对应bin/com/javaeye/loader下找到URLClassLoaderTest.class文件,将此文件保存,然后删除整个project;

(3) 在磁盘任何位置建立文件夹com,在com里建立javaeye,在javaeye里建立loader,我建在C盘java目录下,建立完成后将(2)中保存的URLClassLoaderTest.class文件拷贝到其中,如下:



(4) 在非本地Apache Server上任何位置建立文件夹com,在com里建立javaeye,在javaeye里建立loader文件夹,完成后将(2)中保存的URLClassLoaderTest.class文件拷贝到其中,我的非本地计算机IP为192.168.66.250,系统为Linux Redhat, 建立完成后我们可以访问如下图:



 (5) 给出两端端测试代码:

 

Java代码 复制代码 收藏代码
  1.                @Test  
  2. public void testInWeb() throws Exception{   
  3.     URL[] urls = new URL[]{new URL("http://192.168.66.250/root/java/")};   
  4.     URLClassLoader loader = new URLClassLoader(urls);   
  5.     Class clas = loader.loadClass("com.javaeye.loader.URLClassLoaderTest");   
  6.     Method m = clas.getMethods()[0];   
  7.     Object o = clas.newInstance();   
  8.     m.invoke(o);   
  9. }   
  10. @Test  
  11. public void testInFileSystem() throws Exception{   
  12.     URL[] urls = new URL[]{new URL("file:/C:/java/")};   
  13.     URLClassLoader loader = new URLClassLoader(urls);   
  14.     Class clas = loader.loadClass("com.javaeye.loader.URLClassLoaderTest");   
  15.     Method m = clas.getMethods()[0];   
  16.     Object o = clas.newInstance();   
  17.     m.invoke(o);   
  18. }  

 分别运行两端代码他们输出结果都是:

Java代码 复制代码 收藏代码
  1. I am running...  

 分析:

      为什么会出现上述运行结果,很明显是因为com.learn.loader.URLClassLoaderTest对象被加载到内存,此对象中的show方法被执行;

思考:

      Java 语言由于在 Java 虚拟机 (JVM) 上运行而显得与众不同,之所以与众不同是因为Java中已编译的程序是一种特殊的、独立于平台的格式,并非依赖于它们所运行的机器。在很大程度上,这种格式不同于传统的可执行程序格式。与 C 或 C++ 编写的程序不同,Java 程序并不是一个可执行文件,而是由许多独立的类文件组成,每一个文件对应于一个 Java 类。此外,这些类文件并非立即全部都装入内存,而是根据程序需要装入内存。ClassLoader 是 JVM 中将类装入内存的工具。

 

2.jvm classLoader architecture

同样给出一个例子代码:

Java代码 复制代码 收藏代码
  1. public void testClassLoader2() throws Exception{   
  2.         URL[] urls = new URL[]{new URL("http://192.168.66.250/root/java/")};   
  3.         URLClassLoader loader = new URLClassLoader(urls);   
  4.         System.out.println(loader.getClass());   
  5.         System.out.println(loader.getParent().getClass());   
  6.         System.out.println(loader.getParent().getParent().getClass());   
  7.         System.out.println(loader.getParent().getParent().getParent());   
  8.     }  

 

运行结果如下:

Java代码 复制代码 收藏代码
  1. class java.net.URLClassLoader   
  2. class sun.misc.Launcher$AppClassLoader   
  3. class sun.misc.Launcher$ExtClassLoader   
  4. null  

 

要解释这个运行结果需要说明jvm classloader 结构,如下图:



 如图所示,为了实现java安全沙箱模型顶层的类加载器安全机制, java默认采用了 " 双亲委派的加载链 " 结构,图中分为四层。和我们上面运行结果是一一对应的

      最底层:User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类) ,在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。显然java.net.URLClassLoader属于此层;

      AppClassLoader层:System ClassLoader/系统类加载器,主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。java.lang.ClassLoader.getSystemClassLoader()可以得到他,上述sun.misc.Launcher$AppClassLoader属于此层;

      ExtClassloader层:Extension ClassLoader/扩展类加载器,主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作,sun.misc.Launcher$ExtClassLoader属于此层;

      最顶层:Bootstrap ClassLoader/启动类加载器,主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作,为什么对应这层输出为null?是因为Bootstrap是用C++编写的,我们在Java中看不到它,是null;

一看你就懂,超详细java中的ClassLoader详解

ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于某些框架开发者来说却非常常见。理解ClassLoader的加载机制,也有利于我们编写出更高效的代码。ClassLo...
  • briblue
  • briblue
  • 2017年02月10日 19:26
  • 39687

深度分析Java的ClassLoader机制(源码级别)

http://www.hollischuang.com/archives/199 写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完...
  • zdy0_2004
  • zdy0_2004
  • 2015年12月14日 17:12
  • 1642

java反射机制剖析(二)— Class Loader

上一篇博客简要的提了一下java反射机制中涉及到的一些相关知识,那么ClassLoader就是其中之一。本篇博客就详细的对ClassLoader做一个相对深入的了解。作为了解需要知道的是,其实类类型(...
  • zhuojiajin
  • zhuojiajin
  • 2014年08月31日 18:34
  • 3220

深度分析 Java 的 ClassLoader 机制(源码级别)

Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoader的l...
  • Jason_huzhe
  • Jason_huzhe
  • 2016年05月05日 09:39
  • 626

Java 自定义 ClassLoader 实现隔离运行不同版本jar包的方式

1. 应用场景有时候我们需要在一个 Project 中运行多个不同版本的 jar 包,以应对不同集群的版本或其它的问题。如果这个时候选择在同一个项目中实现这样的功能,那么通常只能选择更低版本的 jar...
  • t894690230
  • t894690230
  • 2017年06月14日 21:16
  • 2214

利用自定义的 ClassLoader 加密 Java Class 文件

本文演示利用自定义的 ClassLoader 加密 Java Class 文件 首先,我们定义一个需要被加密的Java Class: classload.MyClassBase。 为了让客户端使用...
  • xidianliuy
  • xidianliuy
  • 2016年05月31日 11:58
  • 4214

一看你就懂,超详细java中的ClassLoader详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 目录(?)[-] Class文件的认识你还记得java环境变量吗 JAVA_HOMEPATHCLASSPATH环境变量的设置与查看 J...
  • andyzhaojianhui
  • andyzhaojianhui
  • 2017年06月01日 11:05
  • 543

JAVA反射机制深入学习(三)ClassLoader类装载器介绍

接下来介绍下JAVA中非常重要的一个类ClassLoader(类装载器) 类装载器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件。主要工作由ClassLoader及其子类负责,Clas...
  • icarus_wang
  • icarus_wang
  • 2016年05月29日 12:55
  • 860

Class热替换与卸载

原文地址:http://www.importnew.com/22462.html 概述 名词解释:所谓热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用。本文主...
  • Mr__fang
  • Mr__fang
  • 2016年12月30日 15:44
  • 1117

ClassLoader的工作原理(Java中和Andriod中的一些区别)

早期使用过 Eclipse 等 Java 编写的软件的同学可能比较熟悉,Eclipse 可以加载许多第三方的插件(或者叫扩展),这就是动态加载。这些插件大多是一些 Jar 包,而使用插件其实就是动态加...
  • zcxwww
  • zcxwww
  • 2016年12月14日 11:18
  • 804
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java ClassLoader
举报原因:
原因补充:

(最多只允许输入30个字)