ClassLoader 提供了两个方法用于从装载的类路径中取得资源
classloader.getresourceasstream(name)原理解析
ClassLoader.getResourceAsStream(name) 是 Java 中用于从类加载器的类路径上获取资源文件流的方法。
这个方法在读取配置文件、图像、音频等资源时非常有用。
以下是关于该方法工作原理的详细解析:1. 类加载器(ClassLoader)Java 使用类加载器来动态加载 Java 类。
类加载器负责从文件系统、网络或其他来源读取类的字节码,并将其转换为 JVM 可以理解的格式。
Java 中的每个类都是由某个类加载器加载的。
类加载器之间存在父子关系,形成一个树状结构。
通常,每个 Java 应用至少有三个类加载器:引导类加载器(Bootstrap ClassLoader):加载 JDK 中的核心类库,如 ng.* 等。
它不是由 Java 实现的,而是由 JVM 的原生代码实现的。
扩展类加载器(Extension ClassLoader):加载 JDK 的扩展目录(通常是 lib/ext 目录或 JAVA_HOME/jre/lib/ext)中的 JAR 包和类文件。
系统类加载器(System ClassLoader):加载 CLASSPATH 环境变量中指定的类库,它是应用程序默认的类加载器。
2. getResourceAsStream(name) 方法getResourceAsStream(name) 方法用于从类加载器的类路径中查找并返回一个资源的输入流。
资源的名称是相对于类路径的。
资源查找:当调用 getResourceAsStream(name) 方法时,类加载器会按照特定的算法在类路径中查找资源。
它通常首先检查父类加载器是否有该资源,如果没有,再检查自己的资源。
资源名称:资源的名称是相对于“包”的。
例如,如果有一个名为 com.example.MyClass 的类,并且它位于一个名为 MyClass.class 的文件中,那么与该类在同一个目录下的名为config.properties 的文件的资源名称就是 com/example/config.properties。
getclassloader.getresource用法
getclassloader.getresource用法Java语言中的ClassLoader类起到了非常重要的作用,主要用于加载类文件。
在实际的开发中,我们需要加载一些配置文件、资源文件等,这时就可以使用ClassLoader.getResouce()方法来获取这些资源。
本文将深入探讨“getClassLoader.getResouce()”方法的使用方法以及注意事项。
一、ClassLoader的概念ClassLoader是Java中的一个类,它主要用于动态加载类,也可以用于加载其他类型的资源文件。
当Java程序运行时,会默认有一个系统ClassLoader,这个ClassLoader主要用于加载JDK自带的类库和应用程序所在的类和资源。
由于Java的ClassLoader采用的是类似于“双亲委派”模型的机制,这意味着当我们需要加载某个类时,系统会首先从父类ClassLoader中查找是否已经加载了该类,如果父类ClassLoader没有加载该类,则会由当前的ClassLoader自己加载,这样可以避免重复加载。
ClassLoader可以被用户自定义,这样我们就可以利用自定义ClassLoader加载自己的类和资源。
二、ClassLoader.getResource()的使用方法当我们需要加载一些配置文件、资源文件等时,可以使用ClassLoader.getResource()方法来获取。
应该注意的是,ClassLoader.getResouce()方法得到的是资源文件的URL,不是一个普通的文件路径。
下面是示例代码:``` //获取当前类的ClassLoader ClassLoader classLoader = getClass().getClassLoader(); //获取所需要的资源文件的URL URL resourceUrl = classLoader.getResource("config.properties"); ```以上代码中,我们首先获取了当前类的ClassLoader,接着通过ClassLoader.getResource()方法获取了config.properties文件的URL。
java classloader使用
java classloader使用Java的ClassLoader是Java虚拟机(JVM)在运行时动态加载类的机制之一。
ClassLoader负责将Java字节码转换成可执行的Java类对象,并将其加载到JVM的内存中。
ClassLoader提供了一种机制,使得开发人员可以在运行时动态地加载新的类,并在程序执行过程中改变类的行为。
Java的ClassLoader使用可以参考以下几个方面:1. 类加载的过程:Java类加载器遵循双亲委派模型,即ClassLoader在加载一个类时,首先委派给其父类加载器去加载,只有当父类加载器无法加载时,该加载器才会尝试自己去加载。
这样可以保证类的加载是层级结构的,避免了类的重复加载。
2. 类加载器的种类:Java提供了三种类加载器:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用类加载器(Application ClassLoader)。
在ClassLoader的使用中,可以根据需要选择合适的类加载器,或者自定义类加载器。
3. 自定义类加载器:Java中提供了自定义类加载器的机制,可以通过继承ClassLoader类来实现。
自定义类加载器可以用于加载一些非标准位置的类文件,或者对已有的类加载行为进行定制化。
4. 类加载器的委派机制:在双亲委派模型中,类加载器首先尝试委派给父类加载器去加载类,只有当父类加载器无法加载时,才会尝试自己加载类。
这样可以确保类的加载是层级结构的,避免了类重复加载。
5. 类加载器的破坏:在某些特殊情况下,可能希望打破双亲委派模型的限制,自定义类加载器可以覆盖loadClass()方法,以实现自己的加载逻辑。
6. 动态加载类:Java的ClassLoader提供了动态加载类的机制,可以在运行时动态地加载新的类。
这对于某些需要根据不同条件加载不同类的场景非常有用。
classloader 范围
classloader 范围Classloader(类加载器)是Java虚拟机(JVM)的一个重要组成部分,它负责将Java类加载到内存中,以供程序使用。
Classloader的范围是指它在加载类时所涵盖的范围,即它能够加载的类的位置和来源。
在Java中,ClassLoader可以分为三个范围:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。
1. 引导类加载器(Bootstrap ClassLoader):引导类加载器是JVM自身的一部分,它负责加载Java虚拟机自身需要的基础类,如ng包下的类。
引导类加载器是无法被Java代码直接调用或访问的,它是用C++实现的,并由JVM实例初始化。
2. 扩展类加载器(Extension ClassLoader):扩展类加载器用于加载Java的扩展库,它主要负责加载Java平台扩展目录(Java Home/jre/lib/ext)下的JAR文件。
扩展类加载器是由uncher$ExtClassLoader实现的,并由Java标准扩展机制提供。
3. 应用程序类加载器(Application ClassLoader):应用程序类加载器是最常用的类加载器,在Java应用程序中被广泛使用。
它负责加载程序的classpath中的类,包括应用程序自身的类和第三方库的类。
这个类加载器是通过uncher$AppClassLoader实现的。
类加载器的范围决定了类的加载顺序和加载位置。
当一个类被加载时,会首先由引导类加载器进行加载。
如果引导类加载器无法加载该类,会将该请求传递给扩展类加载器。
如果扩展类加载器仍然无法加载,最后轮到应用程序类加载器进行加载。
如果所有的类加载器均无法加载该类,将抛出ClassNotFoundException异常。
classloader的原理,举出应用场景及工作实例
classloader的原理,举出应用场景及工作实例ClassLoader的原理ClassLoader(类加载器)是Java虚拟机的一个重要组成部分,它负责将Java字节码文件加载到内存中,并生成对应的Java类。
ClassLoader的原理涉及到Java虚拟机的类加载机制,下面将详细介绍ClassLoader的原理、应用场景和工作实例。
ClassLoader的原理主要包括以下几个方面:1. 类加载的过程类加载是指将类的字节码文件加载到内存中,并生成对应的Java类。
类的加载过程可以分为以下几个步骤:(1)加载:通过类的全限定名(例如com.example.MyClass)在文件系统或网络中查找对应的字节码文件,找到后将其读取到内存中。
(2)连接:连接是指将已经加载的类与其他的类、接口或者静态变量进行关联。
连接包括验证、准备和解析三个阶段。
- 验证:验证阶段主要是对字节码文件进行校验,确保其符合Java虚拟机的规范。
- 准备:准备阶段主要是为类的静态变量分配内存,并设置默认值。
- 解析:解析阶段主要是将类、接口或者静态变量与实际内存地址进行关联。
(3)初始化:初始化阶段是类加载的最后一个阶段,主要是执行类的静态代码块和静态变量的初始化。
2. 类加载器的分类Java虚拟机中存在多个不同类型的类加载器,主要分为以下几种:(1)引导类加载器(Bootstrap ClassLoader):负责加载Java 核心类库,它是Java虚拟机自身内嵌的一部分,不同的Java虚拟机实现可能不同。
(2)扩展类加载器(Extension ClassLoader):负责加载Java 扩展类库,一般对应于Java虚拟机的jre/lib/ext目录或java.ext.dirs 系统属性指定的路径。
(3)应用程序类加载器(Application ClassLoader):负责加载应用程序的类,一般对应于CLASSPATH 环境变量指定的路径或者用户自定义的路径。
classloader加载原理
classloader加载原理classloader是java中一个比较重要的类加载器,每一个程序和类都会存在一个classloader,classloader有三种主要的工作:加载类的二进制字节流、连接、初始化。
一、Classloader加载机制1、首先classloader会按照特定的方式去搜索类文件,当它找到了相应的类文件之后,它会将这个类文件转换成为二进制字节流,这里涉及到编译程序,classloader会使用编译程序将源程序编译成可执行文件。
2、接下来classloader会将这些二进制字节流存储在内存中,然后classloader会连接这些字节流,这一步是它将这些字节流组装成一个完整的类文件,这里涉及到类的加载,这些加载的类可以被访问,但是它们的代码还未被执行。
3、最后classloader会初始化这些加载的类,这一步就是它将这些类的代码执行,这里classloader会执行所有类变量的初始化,同时也会执行所有静态代码块的内容,最后我们就可以得到一个完整的类文件。
二、Classloader的三种类型1、Bootstrap Classloader:它是用来加载JRE的核心类的,它的实现是C++语言,它的加载范围是从<JAVA_HOME>lib下面开始,这个类加载器不需要程序员编写任何外部类。
2、Extension Classloader:它是用来加载扩展类的,从<JAVA_HOME>libext开始加载,它继承自Bootstrap Classloader,这种类加载器也不需要程序员手动编写任何外部类。
3、Application Classloader:它是用来加载程序类的,它继承自Extension Classloader,它从ClassPath(来自系统变量或者命令行参数)所指定的路径中加载类,但是它不会加载扩展类。
三、Classloader安全机制1、安全性验证:Classloader在加载类的时候会先验证这个类文件,检查它是否符合class文件格式,其次classloader会过滤掉由它本身加载的不安全的类,这涉及到安全管理器的配置,例如:可以设置它只能加载特定的域名下的类文件。
classloadergetresource方法详解
classloadergetresource方法详解在Java语言中,ClassLoader类是一个重要的类,它在Java虚拟机中用来加载Java类文件或者其他相关资源文件。
相信很多Java开发者都会用到ClassLoader类的getResource()方法来获取资源文件,那么今天我们就来详细讲解一下ClassLoader中的getResource()方法。
一、ClassLoader定义ClassLoader是一个作用在Java虚拟机的类,它用来加载类文件或者其他的资源文件。
Java虚拟机通过该类的实例,通过调用ClassLoader中的findClass()方法,加载指定包名称的类文件到虚拟机运行环境中,从而形成Java代码执行的最后环节。
二、getResource()介绍getResource()是ng.ClassLoader中的一个基础函数,它用于在指定的class loader的classpath中搜索得到指定name的资源。
getResource()方法可以用URL对象的形式返回位于给定名称的文件和文件夹的资源。
它在类路径中查找一个具有给定名称的资源,并且返回的是资源的URL对象。
由于该方法是父类加载器的方法,加载资源时会自动委托给其父类加载器。
当找不到资源时返回的将是null值。
三、getResource()与getResourceAsStream()方法区别但是,有些Java开发者会有疑问,在获取资源时,是使用getResource()好还是使用getResourceAsStream()方法更好呢?其实,这两者之间的区别是非常细微的,主要有两个方面:首先是返回值,getResource()方法返回一个URL对象,表示类加载器可以在给定的路径上找到的资源,而getResourceAsStream()方法返回一个输入流对象,表示类加载器可以在给定的路径上找到的资源的数据。
另外,getResourceAsStream()方法中的路径名必须以“/”开头,不然将会找不到指定文件。
classloader类加载器的用法
classloader类加载器的用法Classloader类加载器是Java中负责加载类的重要组件,主要用于在运行时动态加载类。
它的主要用法包括:
1. 加载类:通过指定类的名称或类文件的路径,使用类加载器加载类。
可以使用Class.forName()方法或ClassLoader.loadClass()方法加载类。
2. 查找类:在类路径中搜索指定的类文件,找到并返回类文件的路径或URL。
可以使用ClassLoader.getResource()方法或
ClassLoader.getResourceAsStream()方法来查找类文件。
3. 定义类:将类的字节码加载到内存中,并在运行时动态定义类。
可以使用ClassLoader.defineClass()方法或ClassLoader.defineClass()方法来定义类。
4. 解析类:将类的字节码解析为可执行的代码,并链接类的引用。
可以使用ClassLoader.resolveClass()方法来解析类。
5. 控制类的加载:可以通过自定义类加载器来控制类的加载过程,例如限制只能加载特定的类或从特定的位置加载类。
6. 类的卸载:当不再需要某个类时,可以通过卸载类加载器来清除相关的类。
可以使用ClassLoader.clearAssertionStatus()方法来卸载类。
需要注意的是,使用ClassLoader加载的类会在内存中留有对应的Class对象,这些Class对象会在运行时占用一定的内存空间。
因此,在设计使用ClassLoader 加载大量类的应用程序时,要注意合理使用ClassLoader和控制类的加载。
Java ClassLoader详解
this.instance = (Sample) instance;
}
}
如 代码清单 3 所示,com.example.Sample 类的方法 setSample 接受一个 ng.Object 类型的参数,并且会把该参数强制转换成 com.example.Sample 类型。测试 Java 类是否相同的代码如 代码清单 4 所示。
基本上所有的类加载器都是 ng.ClassLoader 类的一个实例。下面详细介绍这个 Java 类。
ng.ClassLoader 类介绍
ng.ClassLoader 类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后从这些字节代码中定义出一个 Java 类,即 ng.Class 类的一个实例。除此之外,ClassLoader 还负责加载 Java 应用所需的资源,如图像文件和配置文件等。不过本文只讨论其加载类的功能。为了完成加载类的这个职责,ClassLoader 提供了一系列的方法,比较重要的方法如 表 1 所示。关于这些方法的细节会在下面进行介绍。
类加载器的树状组织结构
Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。系统提供的类加载器主要有下面三个:
引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 ng.ClassLoader。
类加载器基本概念
顾名思义,类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 ng.Class 类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象。实际的情况可能更加复杂,比如 Java 字节代码可能是通过工具动态生成的,也可能是通过网络下载的。
classloader getresources 的原理
classloader getresources 的原理Java中的ClassLoader是负责加载类文件的重要组件之一。
其中的`getResources`方法是ClassLoader类提供的一个用于获取资源文件的方法。
让我们来探讨一下`classloader getResources`的原理。
ClassLoader类会在运行时动态加载类文件,并将其转换为Java字节码,以便在Java虚拟机上执行。
每个类都有相应的类加载器,负责从指定的位置加载类文件。
当需要加载类时,Java虚拟机会调用ClassLoader的`loadClass`方法,该方法会首先检查类是否已经加载过,如果没有加载过,则会尝试使用其父加载器来加载。
`getResources`方法是ClassLoader的一个实例方法,用于获取指定路径下的所有资源文件。
它会搜索在类加载器的类路径中,包括JAR文件和目录中的所有资源文件,并返回一个Enumeration对象,该对象包含了所有符合条件的资源文件路径。
在Java中,资源文件可以是配置文件、图像文件、音频文件等。
通过调用`getResources`方法,我们可以获取这些资源文件的路径,然后进一步读取、解析、加载或者执行相应操作。
下面是一个示例代码,使用ClassLoader的`getResources`方法来获取资源文件路径的实例:```javaimport java.io.IOException;import .URL;import java.util.Enumeration;public class ResourceLoader {public static void main(String[] args) throws IOException {ClassLoader classLoader = ResourceLoader.class.getClassLoader();Enumeration<URL> resources = classLoader.getResources("config.properties");while (resources.hasMoreElements()) {URL resource = resources.nextElement();System.out.println("Resource Path: " + resource.getPath());}}}```以上代码中,我们通过`ResourceLoader.class.getClassLoader()`获取当前类的ClassLoader实例。
Java反射机制:(四)类的加载器ClassLoader
Java反射机制:(四)类的加载器ClassLoader⼀、类加载器 1、类加载器概述 在开发中会遇到 ng.ClassNotFoundException 和 ng.NoClassDefError,想要更好解决这类问题,或者在⼀些特殊的应⽤场景,⽐如需要⽀持类的动态加载或需要对编译后的字节码⽂件进⾏加密解密操作,那么需要你⾃定义类加载器,因此了解类加载器及其加载机制成为了Java开发必备技能之⼀。
2、类加载器 类加载的作⽤:完成类的加载。
将class⽂件字节码内容加载到内存中,并将这些静态数据转换成⽅法区的运⾏时数据结构,然后在堆中⽣成⼀个代表这个类的ng.Class对象,作为⽅法区中类数据的访问⼊⼝。
类缓存:标准的JavaSE类加载器可以按要求查找类,但⼀旦某个类被加载到类加载器中,它将维持加载(缓存)⼀段时间。
不过JVM垃圾回收机制可以回收这些Class对象。
3、类加载器作⽤ (1)本质⼯作:类加载器的本质⼯作就是⽤于加载类; (2)类缓存:加载到 JVM 中的类会缓存⼀段时间; (3)加载⽂件:类加载器还可以⽤来加载“类路径下”的资源⽂件。
⼆、类加载器的分类 1、分类 类加载器作⽤是⽤来把类(class)装载进内存的。
JVM 规范定义了如下类型的类的加载器。
2、引导类加载器(Bootstrap Classloader),⼜称为根类加载器 它负责加载 Java 的核⼼库(JAVA_HOME/jre/lib/rt.jar 等或 sun.boot.class.path 路径下的内容),是⽤原⽣代码(C/C++)来实现的,并不继承⾃ng.ClassLoader,所以通过 Java 代码获取引导类加载器对象将会得到 null。
(只有核⼼类库如 String 才使⽤引导类加载器) 3、扩展类加载器(Extension Classloader) 它由 uncher$ExtClassLoader 实现,是 ng.ClassLoader 的⼦类,负责加载 Java 的扩展库(JAVA_HOME/jre/ext/*.jar或java.ext.dirs路径下的内容) 4、应⽤程序类加载器(Application Classloader) 它由 nuncher$AppClassLoader 实现,是 ng.ClassLoader 的⼦类,负责加载 Java 应⽤程序类路径(classpath、java.class.path)下的内容。
关于Class.getResource和ClassLoader.getResource的路径问题===
Java中取资源时,经常用到Class.getResource和ClassLoader.getResource,这里来看看他们在取资源文件时候的路径问题。
Class.getResource(String path)path不以’/'开头时,默认是从此类所在的包下取资源;path 以’/'开头时,则是从ClassPath根下获取;什么意思呢?看下面这段代码的输出结果就明白了:package testpackage;public class TestMain {public static void main(String[] args) {System.out.println(TestMain.class.getResource(""));System.out.println(TestMain.class.getResource("/"));}}输出结果:file:/E:/workspace/Test/bin/testpackage/file:/E:/workspace/Test/bin/上面说到的【path以’/'开头时,则是从ClassPath根下获取;】在这里就是相当于bin目录(Eclipse环境下)。
再来一个实例,假设有如下Project结构:如果我们想在TestMain.java中分别取到1~3.properties文件,该怎么写路径呢?代码如下:package testpackage;public class TestMain {public static void main(String[] args) {// 当前类(class)所在的包目录System.out.println(TestMain.class.getResource(""));// class path根目录System.out.println(TestMain.class.getResource("/"));// TestMain.class在<bin>/testpackage包中// 2.properties 在<bin>/testpackage包中System.out.println(TestMain.class.getResource("2.properties"));// TestMain.class在<bin>/testpackage包中// 3.properties 在<bin>/testpackage.subpackage包中System.out.println(TestMain.class.getResource("subpackage/3.properties"));// TestMain.class在<bin>/testpackage包中// 1.properties 在bin目录(class根目录)System.out.println(TestMain.class.getResource("/1.properties"));}}※Class.getResource和Class.getResourceAsStream在使用时,路径选择上是一样的。
JavaClassLoader原理深入讲解
JavaClassLoader原理深⼊讲解Java ClassLoader原理深⼊讲解 JAVA启动后,是经过JVM各级ClassLoader来加载各个类到内存。
为了更加了解加载过程,下⾯为⼤家深⼊讲解Java ClassLoader原理,仅供参考! 当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构: bootstrap classloader | extension classloader | system classloader bootstrap classloader -引导(也称为原始)类加载器,它负责加载Java的核⼼类。
在Sun的JVM中,在执⾏java的命令中使⽤-Xbootclasspath选项或使⽤ - D选项指定sun.boot.class.path系统属性值可以指定附加的类。
这个加载器的是⾮常特殊的,它实际上不是 ng.ClassLoader的⼦类,⽽是由JVM⾃⾝实现的。
⼤家可以通过执⾏以下代码来获得bootstrap classloader加载了那些核⼼类库: URL[] urls=uncher.getBootstrapClassPath().getURLs(); for (int i = 0; i < urls.length; i++) { System.out.println(urls.toExternalform()); } 在我的计算机上的结果为: ⽂件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/dom.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/sax.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xalan-2.3.1.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xercesImpl-2.0.0.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xml-apis.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xsltc.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/rt.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/i18n.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/sunrsasign.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/jsse.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/jce.jar ⽂件:/C:/j2sdk1.4.1_01/jre/lib/charsets.jar ⽂件:/C:/j2sdk1.4.1_01/jre/classes 这时⼤家知道了为什么我们不需要在系统属性CLASSPATH中指定这些类库了吧,因为JVM在启动的时候就⾃动加载它们了。
理解 Class.getResourceAsStream()
理解Class.getResourceAsStream()ClassLoader提供了两个方法用于从装载的类路径中取得资源:public URL getResource(String name);public InputStream getResourceAsStream(String name);这里name是资源的类路径,它是相对与“/”根路径下的位置。
getResource得到的是一个URL对象来定位资源,而getResourceAsStream取得该资源输入流的引用保证程序可以从正确的位置抽取数据。
然而,程序中调用的通常并不是ClassLoader的这两个方法,而是Class的getResource和getResourceAsStream方法,因为Class对象可以从你的类得到(如YourClass.class或YourClass.getClass()),而ClassLoader则需要再调用一次YourClass.getClassLoader()方法,但根据JDK文档的说法,Class对象的这两个方法其实是“委托”(delegate)给装载它的ClassLoader 来做的,所以只需要使用Class对象的这两个方法就可以了。
举例说明:mypackage.Hello.class.getResourceAsStream("/config/config.ini");从classpath下的config相对路径中读取config.ini另外一篇protected InputStream getConfigurationInputStream(String resource) throws HibernateException {InputStream stream = Environment.class.getResourceAsStream(resource);if (stream==null) {throw new Exception(resource + " not found");}return stream;}client应该这么写://hibernate.cfg.xml位于classes目录下(classPath目录)InputStream stream = getConfigurationInputStream("/hibernate.cfg.xml");如果资源是.property的配置文件,则可以这么装载Properties property=new Properties();property.load(stream);总起来可以这么写:public Properties getPropFromFile(String filePath){InputStream stream = Environment.class.getResourceAsStream(resource);if (stream==null) {throw new Exception(resource + " not found");}Properties property=new Properties();property.load(stream);return stream;}遗留问题:看了以上文档我还没弄明白InputStreamReader in = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("db.sql"));里面sql文件的路径怎么写就是找不到。
Java类加载器ClassLoader用法解析
Java类加载器ClassLoader⽤法解析这篇⽂章主要介绍了Java类加载器ClassLoader⽤法解析,⽂中通过⽰例代码介绍的⾮常详细,对⼤家的学习或者⼯作具有⼀定的参考学习价值,需要的朋友可以参考下正⽂当程序主动使⽤某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进⾏初始化。
如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化。
⼀、类加载过程1.加载加载指的是将类的class⽂件读⼊到内存,并为之创建⼀个ng.Class对象,也就是说,当程序中使⽤任何类时,系统都会为之建⽴⼀个ng.Class对象。
类的加载由类加载器完成,类加载器通常由JVM提供,这些类加载器也是前⾯所有程序运⾏的基础,JVM提供的这些类加载器通常被称为系统类加载器。
除此之外,开发者可以通过继承ClassLoader基类来创建⾃⼰的类加载器。
通过使⽤不同的类加载器,可以从不同来源加载类的⼆进制数据,通常有如下⼏种来源。
从本地⽂件系统加载class⽂件,这是前⾯绝⼤部分⽰例程序的类加载⽅式。
从JAR包加载class⽂件,这种⽅式也是很常见的,前⾯介绍JDBC编程时⽤到的数据库驱动类就放在JAR⽂件中,JVM 可以从JAR⽂件中直接加载该class⽂件。
通过⽹络加载class⽂件。
把⼀个Java源⽂件动态编译,并执⾏加载。
类加载器通常⽆须等到“⾸次使⽤”该类时才加载该类,Java虚拟机规范允许系统预先加载某些类。
2.链接当类被加载之后,系统为之⽣成⼀个对应的Class对象,接着将会进⼊连接阶段,连接阶段负责把类的⼆进制数据合并到JRE 中。
类连接⼜可分为如下3个阶段。
1)验证:验证阶段⽤于检验被加载的类是否有正确的内部结构,并和其他类协调⼀致。
Java是相对C++语⾔是安全的语⾔,例如它有C++不具有的数组越界的检查。
这本⾝就是对⾃⾝安全的⼀种保护。
classloader的使用
classloader的使用ClassLoader是Java虚拟机(JVM)的一个重要组件,负责加载Java类文件到内存中,并生成对应的Class对象。
它主要有以下几种使用方式:1. 系统类加载器(System ClassLoader):也称为应用类加载器,负责加载Java应用程序的相关类。
可以通过Thread.currentThread().getContextClassLoader()方法获取当前线程的类加载器。
2. 扩展类加载器(Extension ClassLoader):负责加载Java的扩展类库(位于%JRE_HOME%/lib/ext目录下)。
扩展类加载器是系统类加载器的父加载器。
3. 引导类加载器(Bootstrap ClassLoader):也称为根类加载器,负责加载JVM自身的类。
它是Java虚拟机实现的一部分,一般无法直接获取到引导类加载器的引用。
4. 自定义类加载器:ClassLoader提供了一些扩展点,可以自定义类加载器来实现特定的类加载行为。
通过继承ClassLoader类,重写findClass()方法,可以实现自定义的类加载逻辑。
使用ClassLoader加载类的步骤如下:1. 创建ClassLoader对象:可以使用系统类加载器或自定义的类加载器。
2. 调用ClassLoader的loadClass()方法:传入类的全限定名,返回一个Class对象。
3. 使用获取到的Class对象进行相关操作:如实例化对象、调用方法等。
注意事项:- ClassLoader只负责加载类文件,对于类的初始化操作需要在使用时进行。
- 在多个ClassLoader中加载同一个类,可能会导致类的不一致。
因此,通常建议使用同一个ClassLoader加载相关的类。
- ClassLoader的双亲委派模型会根据不同的类加载器的继承关系,按照从上到下的顺序查找类文件。
classloader机制 -回复
classloader机制-回复关于`classloader机制`的文章。
第一步:什么是`classloader机制`?在Java中,`classloader机制`是用来加载Java类的一种机制。
它负责将编译好的Java源代码文件转换成Java虚拟机可以识别和执行的二进制字节码文件。
第二步:为什么需要`classloader机制`?在Java中,类的加载是一个动态的过程。
在程序运行过程中,可能会动态地加载、卸载和重载类,而不仅仅是在程序启动时加载。
`classloader机制`的主要作用包括:1. 实现动态加载:在Java中,类的加载是按需加载的。
当程序需要使用某个类时,`classloader机制`会动态地从文件系统、网络或其他来源加载类的定义并创建类的实例。
这种动态加载的能力使得Java可以更加灵活地处理各种情况。
2. 实现类的版本管理和隔离:通过`classloader机制`,可以实现在同一个Java虚拟机中加载多个版本的同一个类。
这种灵活性使得Java应用程序可以同时运行不同版本的库和框架。
3. 提供类的安全性检查:`classloader机制`通过实施安全策略,可以对动态加载的类进行安全性检查,以确保类的来源和内容的可靠性。
第三步:`classloader机制`的基本原理是什么?`classloader机制`的基本原理可以概括为以下几个步骤:1. 指定类的全限定名:当程序需要使用某个类时,需要指定该类的全限定名(即包名加类名)。
2. 定位和加载类的字节码文件:`classloader机制`会根据类的全限定名去查找对应的字节码文件。
这个过程可以是从文件系统、网络或其他来源加载类的字节码文件。
3. 创建类的定义和实例:当加载器找到类的字节码文件后,会将字节码文件转换成一个Java类。
然后,可以使用这个类来创建类的实例。
4. 继续加载类的依赖:当一个类被加载时,它可能依赖于其他类。
`classloader机制`会自动递归地加载这些依赖的类,并按照依赖的先后关系进行加载。
classloader.getresourceasstream(name)原理解析
classloader.getresourceasstream(name)原理解析Java中的Classloader类是Java虚拟机(JVM)中的一个重要组件,用于加载Java类文件到内存中,并在运行时动态地引入类和资源。
其中的一个重要方法是getResourceAsStream(String name),它通过名称获取指定资源的输入流。
本文将对classloader.getResourceAsStream(name)方法的原理进行解析。
一、Classloader的作用和概述Classloader是Java中的一个重要组件,它负责将类文件加载到内存中,并创建对应的Class对象。
每个Java虚拟机实例都有一个默认的类加载器(Bootstrap Classloader),其负责加载Java核心类库。
Java中的类加载器是以层次结构的形式组织的,并且虚拟机可以具有多个类加载器。
二、Classloader.getResourceAsStream(name)方法的作用Classloader中的getResourceAsStream(name)方法用于获取指定资源(如文件、图片等)的输入流对象。
该方法可以通过相对路径或绝对路径来定位和读取资源文件。
它往往用于加载项目中的配置文件、静态资源或其他需要以输入流的形式读取的文件。
三、Classloader.getResourceAsStream(name)方法的原理解析1. Classloader寻找资源Classloader首先从自身加载类路径开始查找资源文件。
如果找到了对应名称的资源文件,就将其返回为一个InputStream对象。
如果找不到,Classloader会委托父类加载器来寻找资源。
2. 父类加载器寻找资源当Classloader无法找到指定的资源时,会委托父类加载器进行查找。
父类加载器也会按照相同的顺序查找,如果找到了资源文件,就将其返回为一个InputStream对象。
7.ClassLoader类的介绍以及获取方法
7.ClassLoader类的介绍以及获取⽅法⽬录1.ClassLoader类介绍ClassLoader是⼀个抽象类。
除了启动类加载器,所有的类加载器都继承⾃ClassLoader。
扩展类加载器和应⽤程序类加载器都是间接继承⾃ClassLoader。
Launcher类是JVM的⼊⼝应⽤。
扩展类加载器和应⽤程序类加载器都是定义在Launcher类的内部类。
ClassLoader类的获取⽅法:例⼦:public class ClassLoaderTest2 {public static void main(String[] args) {try {//1.获取某个类的ClassLoader。
这⾥获取的是String类的ClassLoader。
由于java核⼼api是⽤引导类加载器加载的,所以输出为null。
ClassLoader classLoader = Class.forName("ng.String").getClassLoader();System.out.println(classLoader); // null//2.获取当前线程上下⽂的ClassLoader。
当前是在ClassLoaderTest2 类下,所以获取的是应⽤程序类加载器ClassLoader classLoader1 = Thread.currentThread().getContextClassLoader();System.out.println(classLoader1);// AppClassLoader//3.获取系统的ClassLoaderClassLoader classLoader2 = ClassLoader.getSystemClassLoader().getParent();//系统类加载器的上层是扩展类加载器。
System.out.println(classLoader2);// ExtClassLoader} catch (ClassNotFoundException e) {e.printStackTrace();}}}。
Javaclass.getClassLoader().getResource()获取资源路径
Javaclass.getClassLoader().getResource()获取资源路径在开发中经常需要获取资源⽂件路径,例如读写配置⽂件等。
Java也提供很多⽅法来获取这些路径,下⾯就⼏种常⽤到的作⼀下讨论区分:1、xxx.class.getClassLoader().getResource(“”).getPath();获取src资源⽂件编译后的路径(即classes路径)2、xxx.class.getClassLoader().getResource(“⽂件”).getPath();获取classes路径下“⽂件”的路径3、xxx.class.getResource(“”).getPath();缺少类加载器,获取xxx类经编译后的xxx.class路径4、this.getClass().getClassLoader().getResource(“”).getPath();以上三种⽅法的另外⼀种写法5、request().getSession().getServletContext().getRealPath(“”);获取web项⽬的路径例如:System.out.println(FileUpLoadAction.class.getClassLoader().getResource("conf.properties").getPath());System.out.println(FileUpLoadAction.class.getClassLoader().getResource("").getPath());System.out.println(FileUpLoadAction.class.getResource("").getPath());System.out.println(this.getClass().getClassLoader().getResource("").getPath());System.out.println(ServletActionContext.getRequest().getSession().getServletContext().getRealPath("login.jsp"));输出依次为:/D:/codes/trunk/client/web/IBMS/myworkspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/webclient/WEB-INF/classes/conf.properties/D:/codes/trunk/client/web/IBMS/myworkspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/webclient/WEB-INF/classes//D:/codes/trunk/client/web/IBMS/myworkspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/webclient/WEB-INF/classes/com/gmi/client//D:/codes/trunk/client/web/IBMS/myworkspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/webclient/WEB-INF/classes/D:\codes\trunk\client\web\IBMS\myworkspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\webclient\login.jsp1此外,对于读写配置⽂件,例如properties⽂件,Java还提供了getResourceAsStream(“⽂件”)⽅法返回⼀个InputStream供读取⽂件:InputStream is = this.getClass().getClassLoader().getResourceAsStream(“conf.properties”);好了,以上也只是⼀部分⽅法,还有诸多不⾜之处,后续补充,欢迎指正。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ClassLoader 提供了两个方法用于从装载的类路径中取得资源:
public URL getResource (String name);
public InputStream getResourceAsStream (String name);
这里name是资源的类路径,它是相对与“/”根路径下的位置。
getResource 得到的是一个URL对象来定位资源,而getResourceAsStream取得该资源输入流的引用保证程序可以从正确的位置抽取数据。
但是真正使用的不是ClassLoader的这两个方法,而是Class的getResource和getResourceAsStream方法,因为Class对象可以从你的类得到(如YourClass.class或 YourClass.getClass()),而ClassLoader则需要再调用一次YourClass.getClassLoader()方法,不过根据JDK文档的说法,Class对象的这两个方法其实是“委托”(delegate)给装载它的ClassLoader 来做的,所以只需要使用 Class对象的这两个方法就可以了。
因此,直接调用 this.getClass()。
getResourceAsStream(String name) ;获取流,静态化方法中则使用ClassLoader.getSystemResourceAsStream (String name) ; 。
下面是一些得到classpath和当前类的绝对路径的一些方法。
你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。
1.this.getClass()。
getResource("")
得到的是当前类class文件的URI目录。
不包括自己!
如:file:/D:/workspace/jbpmtest3/bin/com/test/
this.getClass()。
getResource("/")。
getPath();
如:D:/workspace/jbpmtest3/bin/com/test/
2.this.getClass()。
getResource("/")
得到的是当前的classpath的绝对URI路径。
如:file:/D:/workspace/jbpmtest3/bin/
3.this.getClass() .getClassLoader()。
getResource("")
得到的也是当前ClassPath的绝对URI路径。
如:file:/D:/workspace/jbpmtest3/bin/
4.ClassLoader.getSystemResource("")
得到的也是当前ClassPath的绝对URI路径。
如:file:/D:/workspace/jbpmtest3/bin/
5.Thread.currentThread()。
getContextClassLoader ()。
getResource ("")
得到的也是当前ClassPath的绝对URI路径。
如:file:/D:/workspace/jbpmtest3/bin/
6.ServletActionContext.getServletContext()。
getRealPath(“/”)
Web应用程序中,得到Web应用程序的根目录的绝对路径。
这样,我们只
需要提供相对于Web应用程序根目录的路径,就可以构建出定位资源的绝对路径。
如:file:
/D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtp webapps/WebProject
注意点:
1.尽量不要使用相对于System.getProperty("user.dir")当前用户目录
的相对路径。
这是一颗定时炸弹,随时可能要你的命。
2.尽量使用URI形式的绝对路径资源。
它可以很容易的转变为URI,URL,File对象。
3. 尽量使用相对classpath的相对路径。
不要使用绝对路径。
使用上面ClassLoaderUtil类的public static URL getExtendResource(String relativePath)方法已经能够使用相对于classpath的相对路径定位所有位置的资源。
4.绝对不要使用硬编码的绝对路径。
因为,我们完全可以使用ClassLoader 类的getResource("")方法得到当前classpath的绝对路径。
如果你一定要指定一个绝对路径,那么使用配置文件,也比硬编码要好得多!
获得CLASSPATH之外路径的方法:
URL base = this.getClass()。
getResource(""); //先获得本类的所在位置,如/home/popeye/testjava/build/classes/net/
String path = new File(base.getFile(),"……/……/……/"+name)。
getCanonicalPath(); //就可以得到/home/popeye/testjava/name
另外,如果从ANT启动程序,this.getClass()。
getResource("")取出来的比较怪,直接用JAVA命令行调试就可成功。
FreeMarker的Configuration对象中设置模板路径有以下三种方法:
setDirectoryForTemplateLoading(new File
("/var/tomcat/webapp/project/WEB-INFO/template/"))
getFreemarkerCfg()。
setServletContextForTemplateLoading(arg0, arg1);
setClassForTemplateLoading(clazz, pathPrefix)。