classloader相关

classloader分类

启动类装载器

扩展类装载器

应用装载器

启动类装载器加载java基本api相关的类。

扩展装载器加载JAVA_HOME/jre/lib/ext目录下的class文件

应用装载器加载应用程序相关jar包及程序相关class

启动顺序

启动类装载器---->扩展类装载器---->应用装载器

类装载器执行

类装载采用双亲委托模式,即应用装载器请求它的父装载器(扩展装载器),扩展装载器请求它的父装载器(启动装载器),顶层的装载器一定是启动类装载器,如果父装载器不能返回所需类,就由自己来加载。

类装载器的安全机制

jvm可以有多个classloader,每一个classloader都有一个名称空间唯一标识,只有同一个名称空间内的类采可以相互访问。

如果非启动类装载器试途装载java.lang.Integer类,该操作将被jvm取消,因为Integer经过由启动类装载器装载。

如果某个classloader试途装载一个恶意的class,如java.lang.Virus,该类在相关的父classloader中没有,所以将成功装载,问题是该类位置java.lang包中,这是非常危险的,这表明它可以访问java.lang中的相关类,但是classloader的名称空间不同virus还是不可以访问java.lang中的类,也就是说对于用户级的classloader加载的类只会拥有在同一个classloader同一个包的访问权限。

classloader还有一个安全域的概念,即classloader将被加载的类放入一个安全域中,安全域决定该类在运行时的权限。

相关api

获得boot classloader

sun.misc.Launcher.getBootstrapClassPath()

获得应用classloader

ClassLoader.getSystemClassLoader()

获得扩展classloader

ClassLoader.getSystemClassLoader().getParent()

用户可以自定义classloader

自定义ClassLoader需要继承ClassLoader抽象类,重写findClass方法,这个方法定义了ClassLoader查找class的方式

主要可以扩展的方法有:

findClass          定义查找Class的方式

defineClass       将类文件字节码加载为jvm中的class

findResource    定义查找资源的方式

如果嫌麻烦的话,我们可以直接使用或继承已有的ClassLoader实现,比如

  • java.net.URLClassLoader
  • java.security.SecureClassLoader
  • java.rmi.server.RMIClassLoader
  • sun.applet.AppletClassLoader

Extension ClassLoader 和 App ClassLoader都是java.net.URLClassLoader的子类。

这个是URLClassLoader的构造方法:

public URLClassLoader(URL[] urls, ClassLoader parent)

public URLClassLoader(URL[] urls)

 

你可能感兴趣的:(jvm,ClassLoader)