jvm类加载器的分类

jvm支持两种类型的类加载器,分别为:

引导类加载器

引导类加载器又叫启动类加载器,Bootstrap ClassLoader,有如下的特点:

  • 使用c/c++实现,嵌套在jvm内部
  • 用来加载java的核心库,如jre/lib/rt.jar,resources.jar,或sun.boot.class.path路径下的内容
  • 不继承java.lang.ClassLoader类,因为不是java语言实现的,也没有父类加载类
  • 处于安全考虑,只加载包名为java,javax,sun等开头的类

自定义类加载器

所有派生于抽象类ClassLoader的类,包含扩展加载类, 系统加载类,用户自定义加载类
在这里插入图片描述
**扩展类加载器(Extension ClassLoader)**有如下特点:

  • 父加载类为启动类加载器
  • 派生于ClassLoader类
  • 由java语言编写,sun.misc.Launcher$ExtClassLoader实现
  • 从java.ext.dirs系统属性所指定的目录或从jdk安装目录的jre/lib/ext子目录下加载类库(如果用户创建的jar在此目录也会被扩展类加载器加载)

系统类加载器(又叫应用程序类加载器,AppClassLoader),有如下特点:

  • java语言编写,sun.misc.Launcher$AppClassLoader实现
  • 派生于ClassLoader类
  • 父类加载器为扩展类加载器
  • 负责加载环境classpath或系统属性java.class.path指定路径下的类库
  • 它是程序中默认的类加载器,一般来说java应用类都是由它来加载
  • 通过ClassLoader#getSystemClassLoader()方法可以获取到该类加载器

用户自定义的类加载器
在平时的开发中,类的加载几乎都是由上面的三类加载器中相互配合执行的,那么为何我们需要自定义类加载器这样的操作呢,有如下几点:
**隔离加载类:**中间件如tomcat或其他组件自身用的类怕与其他组件起冲突,所以自定义类加载器来隔离自身所用的类与其他组件的类。
扩展加载源:已知有从文件,压缩包,网络等方式的加载源,如果需要从数据库中加载,那就得自己扩展了。
防止源码泄露:一般生成的字节码都可以用反编译插件来反编译出源码,如果要对源码进行加密保护,则需要自定义类加载器,在加载时进行解密,从而达到防止泄露的目的。

在实现方面,可以通过继承ClassLoader抽象类的方式,并重写findClass()方法,如果没有复杂的需求,也可直接继承URLClassLoader类,这样可以避免编写findClass方法实现及获取字节码流的方式。

ClassLoader的信息

ClassLoader类的方法如下所示:在这里插入图片描述
类结构如下所示:
在这里插入图片描述
获取ClassLoader的方式:
获取当前类的classLoader:clazz.getClassLoader()
获取当前线程上下文的classLoader:Thread.currentThread().getContextClassLoader()
获取系统的classLoader:ClassLoader.getSystemClassLoader()
获取调用者的classLoader:DriverManager.getCallerClassLoader()

猜你喜欢

转载自blog.csdn.net/lyd135364/article/details/120693938
今日推荐