精华内容
下载资源
问答
  • JVM支持两种类型的类加载器,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)。 这里的自定义加载器指的不是开发人员自己定义的类加载器,而是指的所有继承自ClassLoader...

    1.类加载器分类

    JVM支持两种类型的类加载器,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)。
    这里的自定义加载器指的不是开发人员自己定义的类加载器,而是指的所有继承自ClassLoader的类加载器。包括扩展类加载器、应用程序类加载器、用户自定义类加载器(程序员自己写的)三种。
    在这里插入图片描述
    常见的类加载器如下图所示:
    第一个蓝色框表示的是引导类加载器;剩下的所有的类加载器都是自定义的类加载器。BootStrapClassLoader使用C语言实现,自定义类加载器使用Java语言实现。
    注意:图中不是表示的继承关系。扩展类加载器和系统类加载器(应用程序类加载器AppClassLoader)都是继承自ClassLoader,所以将他们划分为自定义加载器。
    在这里插入图片描述
    下面的Java例子,可以帮助理解类加载器之间的关系:

    public class ClassLoaderTest {
        public static void main(String[] args) {
    
            //获取系统类加载器,输出AppClassLoader,说明系统类加载器就是应用程序类加载器
            ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
            System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
    
            //获取系统类加载器的上层:输出ExtClassLoader,说明系统类加载器的上层是扩展类加载器
            ClassLoader extClassLoader = systemClassLoader.getParent();
            System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader@1540e19d
    
            //获取扩展类加载器的上层:输出null,获取不到引导类加载器。虽然获取不到,但是扩展类加载器的上层是引导类加载器
            ClassLoader bootstrapClassLoader = extClassLoader.getParent();
            System.out.println(bootstrapClassLoader);//null
    
            //输出AppClassLoader。说明对于用户自定义类来说:默认使用系统类加载器进行加载
            ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
            System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
    
            //打印的也是null,和获取扩展类的上层的输出是一样。可以证明String类使用引导类加载器进行加载的。扩展开来:---> Java的核心类库都是使用引导类加载器进行加载的。
            ClassLoader classLoader1 = String.class.getClassLoader();
            System.out.println(classLoader1);//null
    
    
        }
    }
    
    

    1.1 引导类加载器(Bootstrap ClassLoader)

    1.引导类加载器使用C/C++语言实现,在JVM内部
    2.用于加载Java核心类库
    3.不继承ClassLoader
    4.还用于加载扩展类加载器和应用程序类加载器
    5.只加载包名为java,javax,sun开头的类
    在这里插入图片描述

    1.2 扩展类加载器(Extension ClassLoader)

    1.使用java语言编写,JVM自带
    2.继承自ClassLoader
    3.父类加载器为扩展类加载器
    4.从java.ext.dirs指定的路径下加载类库;或者从JDK安装目录的jre/lib/ext目录下加载类库。
    5.如果用户自定义的jar包放在jre/lib/ext下,也会自动由扩展类加载器加载
    在这里插入图片描述

    1.3 应用程序类加载器(AppClassLoader或者称为系统类加载器)

    1.使用jaca语言编写,JVM自带
    2.继承自ClassLoader
    3.父类加载器为启动类加载器
    4.负责加载环境变量classpath或系统属性java.class.path指定的类库
    5.java中自己写的类都是由应用程序类加载器加载的
    6.可以通过ClassLoader.getSystemClassLoader()方法获取该类加载器
    在这里插入图片描述

    理解BootstrapClassLoader、ExtClassLoader、AppClassLoader的例子:

    public class ClassLoaderTest1 {
        public static void main(String[] args) {
            System.out.println("**********启动类加载器**************");
            //获取BootstrapClassLoader能够加载的api的路径
            URL[] urLs = sun.misc.Launcher.getBootstrapClassPath().getURLs();//获取到的是通过引导类加载的类库的路径(输出参考“引导类能够加载的类库路径”)
            for (URL element : urLs) {
                System.out.println(element.toExternalForm());
            }
            //从上面的路径中随意选择一个类,来看看他的类加载器是什么:引导类加载器
            ClassLoader classLoader = Provider.class.getClassLoader();
            System.out.println(classLoader); //输出为null。说明是引导类加载器加载的
    
            System.out.println("***********扩展类加载器*************");
            String extDirs = System.getProperty("java.ext.dirs");
            for (String path : extDirs.split(";")) {// 输出参考“扩展类能够加载的类库路径”图
                System.out.println(path);
            }
    
            //从上面的路径中随意选择一个类,来看看他的类加载器是什么:扩展类加载器
            ClassLoader classLoader1 = CurveDB.class.getClassLoader();
            System.out.println(classLoader1);//sun.misc.Launcher$ExtClassLoader@1540e19d
    
        }
    }
    

    引导类能够加载的类库路径:如下图。主要就是jre/lib/目录下面的jar包。
    在这里插入图片描述
    扩展类能够加载的类库路径:如下图。主要是jre/lib/ext目录以及java.ext.dirs指定的路径下的jar包
    在这里插入图片描述

    1.4 用户自定义类加载器(程序员自己写的)

    除了上面3种JVM提供的类加载器之外,程序员还可以自己定义类加载器。(简单了解)
    在这里插入图片描述
    自定义加载器实现步骤:
    在这里插入图片描述
    自定义一个类加载器简单的例子:

    public class CustomClassLoader extends ClassLoader { //继承ClassLoader
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException { //重载findClass方法
    
            try {
                byte[] result = getClassFromCustomPath(name);
                if(result == null){
                    throw new FileNotFoundException();
                }else{
                    return defineClass(name,result,0,result.length);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
    
            throw new ClassNotFoundException(name);
        }
    
        private byte[] getClassFromCustomPath(String name){
            //从自定义路径中加载指定类:细节略
            //如果指定路径的字节码文件进行了加密,则需要在此方法中进行解密操作。(这里可以进行解密操作,防止class文件被反编译)
            return null;
        }
    
        public static void main(String[] args) {
            CustomClassLoader customClassLoader = new CustomClassLoader();
            try {
                Class<?> clazz = Class.forName("One",true,customClassLoader);
                Object obj = clazz.newInstance();
                System.out.println(obj.getClass().getClassLoader());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    

    更多JVM文章请参考我的JVM专栏:https://blog.csdn.net/u011069294/category_10113093.html

    展开全文
  • 分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)。 从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范却没有这么定义,...

    类加载器的分类

    JVM支持两种类型的类加载器 。分别为引导类加载器(Bootstrap ClassLoader)自定义类加载器(User-Defined ClassLoader)。

    从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范却没有这么定义,而是将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器。

    无论类加载器的类型如何划分,在程序中我们最常见的类加载器始终只有3个,如下所示
    在这里插入图片描述
    这里的四者之间是包含关系,不是上层和下层,也不是子系统的继承关系

    我们通过一个类,获取它不同的加载器

    /**
     * @author: 陌溪
     * @create: 2020-07-05-9:47
     */
    public class ClassLoaderTest {
        public static void main(String[] args) {
            // 获取系统类加载器
            ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
            System.out.println(systemClassLoader);
    
            // 获取其上层的:扩展类加载器
            ClassLoader extClassLoader = systemClassLoader.getParent();
            System.out.println(extClassLoader);
    
            // 试图获取 根加载器
            ClassLoader bootstrapClassLoader = extClassLoader.getParent();
            System.out.println(bootstrapClassLoader);
    
            // 获取自定义加载器
            ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
            System.out.println(classLoader);
            
            // 获取String类型的加载器
            ClassLoader classLoader1 = String.class.getClassLoader();
            System.out.println(classLoader1);
        }
    }
    

    得到的结果,从结果可以看出 根加载器无法直接通过代码获取,同时目前用户代码所使用的加载器为系统类加载器。同时我们通过获取String类型的加载器,发现是null,那么说明String类型是通过根加载器进行加载的,也就是说Java的核心类库都是使用根加载器进行加载的。

    sun.misc.Launcher A p p C l a s s L o a d e r @ 18 b 4 a a c 2 s u n . m i s c . L a u n c h e r AppClassLoader@18b4aac2 sun.misc.Launcher AppClassLoader@18b4aac2sun.misc.LauncherExtClassLoader@1540e19d
    null
    sun.misc.Launcher$AppClassLoader@18b4aac2
    null

    虚拟机自带的加载器

    启动类加载器(引导类加载器,Bootstrap ClassLoader)

    • 这个类加载使用C/C++语言实现的,嵌套在JVM内部。
    • 它用来加载Java的核心库(JAVAHOME/jre/1ib/rt.jar、resources.jar或sun.boot.class.path路径下的内容),用于提供JVM自身需要的类
    • 不继承自ava.lang.ClassLoader,没有父加载器
    • 加载扩展类和应用程序类加载器,并指定为他们的父类加载器。
    • 出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类

    扩展类加载器(Extension ClassLoader)

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

    应用程序类加载器(系统类加载器,AppClassLoader)

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

    用户自定义类加载器

    在Java的日常应用程序开发中,类的加载几乎是由上述3种类加载器相互配合执行的,在必要时,我们还可以自定义类加载器,来定制类的加载方式。 为什么要自定义类加载器?

    • 隔离加载类
    • 修改类加载的方式
    • 扩展加载源
    • 防止源码泄漏

    用户自定义类加载器实现步骤:

    • 开发人员可以通过继承抽象类ava.1ang.ClassLoader类的方式,实现自己的类加载器,以满足一些特殊的需求
    • JDK1.2之前,在自定义类加载器时,总会去继承ClassLoader类并重写loadClass()方法,从而实现自定义的类加载类,但是在JDK1.2之后已不再建议用户去覆盖loadclass()方法,而是建议把自定义的类加载逻辑写在findclass()方法中
    • 在编写自定义类加载器时,如果没有太过于复杂的需求,可以直接继承URIClassLoader类,这样就可以避免自己去编写findclass()方法及其获取字节码流的方式,使自定义类加载器编写更加简洁
    • 在这里插入图片描述

    关于ClassLoader

    ClassLoader类,它是一个抽象类,其后所有的类加载器都继承自ClassLoader(不包括启动类加载器
    在这里插入图片描述
    sun.misc.Launcher 它是一个java虚拟机的入口应用
    在这里插入图片描述
    获取ClassLoader的途径

    • 获取当前ClassLoader:class.getClassLoader()
    • 获取当前线程上下文的ClassLoader:Thread.currentThread().getContextClassLoader()
    • 获取系统的ClassLoader:ClassLoader.getSystemClassLoader()
    • 获取调用者的ClassLoader:DriverManager.getCallerClassLoader()
    展开全文
  • 详细错误如下: Creating Service {... Exception in thread "main" java.lang.LinkageError: 正在从引导类加载器加载 JAXB 2.1 API, 但此 RI (来自jar:file:/E:/ji

    详细错误如下:

    Creating Service {http://server.hw.demo/}HelloWorld from class demo.hw.server.HelloWorld
    Exception in thread "main" java.lang.LinkageError: 正在从引导类加载器加载 JAXB 2.1 API, 但此 RI (来自jar:file:/E:/jinwork/cxf/WebContent/WEB-INF/lib/jaxb-impl-2.2.6.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) 需要 2.2 API。请使用授权目录机制将 jaxb-api.jar 放在引导类加载器中。(请参阅 http://java.sun.com/j2se/1.6.0/docs/guide/standards/)
        at com.sun.xml.bind.v2.model.impl.ModelBuilder.<clinit>(ModelBuilder.java:178)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:455)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:303)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:142)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1174)
        at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:162)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:210)
        at javax.xml.bind.ContextFinder.find(ContextFinder.java:368)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
        at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:267)
        at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:265)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.apache.cxf.common.jaxb.JAXBContextCache.createContext(JAXBContextCache.java:265)
        at org.apache.cxf.common.jaxb.JAXBContextCache.getCachedContextAndSchemas(JAXBContextCache.java:172)
        at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:464)
        at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:330)
        at org.apache.cxf.service.factory.AbstractServiceFactoryBean.initializeDataBindings(AbstractServiceFactoryBean.java:86)
        at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:478)
        at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:690)
        at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:540)
        at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:252)
        at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:205)
        at org.apache.cxf.jaxws.ServiceImpl.createPort(ServiceImpl.java:439)
        at org.apache.cxf.jaxws.ServiceImpl.getPort(ServiceImpl.java:312)
        at org.apache.cxf.jaxws.ServiceImpl.getPort(ServiceImpl.java:307)
        at javax.xml.ws.Service.getPort(Service.java:120)
        at demo.hw.client.Client.main(Client.java:54)

    解决办法:

    1.首先获取到endorsed目录。

    public class MainClass {

        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.println(System.getProperty("java.endorsed.dirs"));
        }

    }

    2.找到相应位置,将apache-cxf-2.7.4\lib\endorsed下的jar文件放到对应目录下即可。如果没有endorsed目录,则手动建立该目录。

    展开全文
  • 加载器的介绍 和 的加载过程

    万次阅读 2020-09-24 21:41:01
    引导类加载器 BootStrapClassLoader 扩展类加载器 ExtensionClassLoader 应用程序类加载器 ApplicationClassLoader 三大类加载器可以简单的理解为: BootStrapClassLoader加载的是JVM核心类的类库 ...
  • 类加载器

    热门讨论 2016-01-20 10:32:52
    类加载器 1 什么是类加载器 类加载器就是用来加载类的东西!... bootstrap classloader:引导类加载器,加载rt.jar(JDK基本类库)中的类;  sun.misc.Launcher$ExtClassLoader:扩展类加载器,加
  • 类加载器分为根加载器(bootstrap classloader)、扩展类加载器(ext classloader)、系统类加载器(system classloader)、自定义类加载器(通常继承java.net.URLClassLoader,重写findClass()),它们的关系通常...
  • 问题:SPI 的接口是 Java 核心库的一部分,是由引导类加载器来加载的;SPI 实现的 Java 类一般是由系统类加载器来加载的。引导类加载器是无法找到 SPI 的实现类的,因为它只加载 Java 的核心库。它也不能...
  • 类加载器原理 将class文件字节码内容加载到内存中,并将...1、引导类加载器(C语言编写) 2、扩展类加载器(Java编写) 3、应用程序类加载器(Java编写) 4、自定义类加载器(Java编写) 来测试一下ClassL...
  • Java内置类加载器 ...不是的,原因是Bootstrap Loader(引导类加载器)是用非Java语言实现的,无法获取到该加载器,所以才返回null。 Java内置类加载器的层次结构 启动类加载器、扩展类加载器、应用类加载以及自...
  • JVM类加载器分类

    千次阅读 2019-03-09 11:12:34
    JVM中的类的加载器主要有三种:启动类加载器,拓展类加载器,应用类...启动类加载器(Bootstrap classLoader):又称为引导类加载器,由C++编写,无法通过程序得到。主要负责加载JAVA中的一些核心类库,主要是位于&l...
  • 1 线程上下文类加载器 2 何时使用Thread.getContextClassLoader()? 3 类加载器与Web容器 4 类加载器与OSGi 总结 1 线程上下文类加载器  线程上下文类加载器(context class loader)是从 JDK 1.2 开始引入的...
  • 类加载器[0]内置类加载器

    千次阅读 2017-03-06 14:33:59
    引导类加载器 用于加载JAVA_HOME/jre/lib/rt.jar. 他并不继承自java.lang.ClassLoader,是用C/C++代码实现的。   2、 扩展类加载器 用于加载JAVA_HOME/jre/lib/ext/*.jar 具体实现为sun.misc.Launcher$...
  • Tomcat类加载器(附JVM类加载器简介)  学习tomcat类加载器,... JVM类加载器:引导类加载器(bootstrapclassloader)、扩展类加载器(extension classloader)、系统类加载器(又称应用类加载器,system classload
  • java中的类加载器

    2018-08-12 17:07:54
    java中的类加载器 一、什么是类加载器 ...* 引导类加载器:加载类库里面的类 * 扩展类加载器:加载扩展jar包里面的类 * 系统类加载器:加载应用下的class,包含开发人员写的类,和第三方的jar包!class...
  • Java的类加载器

    千次阅读 2014-04-16 17:32:56
    3) 对于系统提供的类加载器来说,系统类加载器的父类加载器是扩展类加载器,而扩展类加载器的父类加载器是引导类加载器;对于开发人员编写的类加载器来说,其父类加载器是加载此类加载器的类加载器。因为类加载器...
  • 2、创建一个引导类加载器(BootstrapClassloader); 3、引导类加载器创建JVM启动器launcher,由lunacher类创建其他类加载器(扩展类加载器和应用类加载器) 二、类加载的大致过程 1、加载,根据path找到class文件; 2...
  • java类加载器探究

    千次阅读 2015-01-09 15:38:12
    1:启动类加载器也叫引导类加载器 (Bootstrap) 加载JAVA_HOME/lib 下的类 比如rt.jar 2:扩展类加载器(ExtClassLoader) 加载JAVA_HOME/lib/ext 下的类 3:应用程序类加载器(AppClassLoader) 加载应用程序...
  • 深入理解Java类加载器(ClassLoader)

    万次阅读 多人点赞 2017-06-26 09:34:08
    类加载器的任务是根据一个类的全限定名来读取此类的二进制字节流到JVM中,然后转换为一个与目标类对应的java.lang.Class对象实例,在虚拟机提供了3种类加载器,引导(Bootstrap)类加载器、扩展(Extension)...
  • Java进阶之类加载器

    千次阅读 2016-10-09 23:28:05
    当JVM启动时,会形成由三个类加载器组成的初始类加载器层次结构,引导类加载器(bootstrap classloader),扩展类加载器(extension classloader),应用类加载器(system classloader)。三者的关系:bootstrap ...
  • jvm之java类加载机制和类加载器(ClassLoader)的详解

    万次阅读 多人点赞 2018-08-13 15:05:46
    当程序主动使用某个类时,如果该类还未被加载到内存中,则...如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化。 一、类加载过程 1.加载 加载指的是将类的class文件...
  • 其实类加载器的加载机制很简单

    千次阅读 2016-09-06 18:58:46
     1.BootStarp(引导类加载器):负责加载java核心类库,不继承自ClassLoader加载器; 2.Extension(扩展类加载器):负责加载java扩展库(例如sun公司专门为连接数据库设计的JDBC的一组API) 3.Application(系统类...
  • 简介 类是如何加载的,那么必须要面对的几个问题如下 什么是类加载机制? 什么是双亲委任模型? 如何破坏双亲委任模型?...Tomcat 的类加载器是怎么设计的?...引导类加载器(bootstrap class loader):它用...
  • 全面解析Java类加载器

    2021-01-20 03:38:14
    深入理解和探究Java类加载机制—-  1.java.lang.ClassLoader类介绍  java.lang.ClassLoader类的基本职责是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后...  引导类加载器(bootstrap class loade
  • 类加载器的作用

    2021-01-02 23:44:43
    类加载器的作用 类加载的作用:将Class文件字节码内容加载到内存中,并将这些静态数据转成方法区的运行时数据结构,然后再堆中生成一个代表整个类的Java.lang.Class对象,作为方法区...引导类加载器:用C++编写的,时
  • 1.引导类加载器
  • 类加载器由上到下有引导类加载器,继承类加载器,应用程序加载器,你还可以自己自定义加载器。类加载器在加载类的时候,采用的是代理模式,具体代理是双亲代理模式这里systemout输出的是“123”,为什么kkk.toString...
  • 类加载器一、类加载器的作用二、Java虚拟机类加载器结构1. 引导类(启动类)加载器2. 扩展类加载器3. 系统类加载器三、类加载器的加载机制1. 全盘负责2. 双亲委派3. 缓存机制四、自定义类加载器 一、类加载器的作用 &...
  • 1:启动类加载器也叫引导类加载器 (Bootstrap) 加载JAVA_HOME/lib 下的类 比如rt.jar 2:扩展类加载器(ExtClassLoader) 加载JAVA_HOME/lib/ext 下的类 3:应用程序类加载器(AppClassLoader) 加载应用程序...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 55,827
精华内容 22,330
关键字:

引导类加载器