- 浏览: 331051 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (212)
- spring (21)
- design pattern(java) (12)
- linux-shell (28)
- java-thread (20)
- java-collection (6)
- java-reflect (9)
- mysql (11)
- java-io (7)
- java-util&lang&io (3)
- algorithm (3)
- interview (2)
- tools-eclipse (2)
- tools-maven (1)
- web-script (1)
- java组建 (13)
- 博客收藏 (1)
- 架构设计与实践 (10)
- active-mq (6)
- java-jvm&性能&原理 (27)
- tomcat (2)
- flume (1)
- serialization (2)
- git (1)
- cache&redis (8)
- guava (1)
- zookeeper (3)
- socket&tcp&udp&http (6)
- test (1)
最新评论
-
bbls:
有用有用有用
java-jvm-jstack-(监视器和锁的概念) -
王新春:
小侠有点帅哦 写道此流怎么关闭新春这个实现 可以不关闭的,哈哈 ...
源码剖析之java.io.ByteArrayOutputStream -
小侠有点帅哦:
此流怎么关闭新春
源码剖析之java.io.ByteArrayOutputStream -
cumt168:
写的很好为什么初始化参数,年轻代-Xmn10M def new ...
jvm之内存申请过程分析 -
ronin47:
应该是跟共享域名思路差不多,根据cookie的key作判断
跨域:一种通过服务端解决跨域的实现
深刻理解java的配置环境以及java的执行过程对做好开发是十分重要的。
类加载器ClassLoader 便是其中非常重要的概念。
本文简单并演示Java类加载器的一些特点,不妥之处,敬请指出。
背景:
A.java 引用 了B.jar 中的一个文件,B.jar 包中的C.class 使用了C.class.getResourceAsStream("/jdbc.xml")获取资源文件。 B.jar 做一个独立的功能的工具,使用方只要提供对应的jdbc.xml 配置文件即可在dev qa prod 各个环境使用啦。
但是问题来了,在web下和java命令行情况下,jdbc.xml 文件放置的位置大不相同,因为web 和java命令下 B.jar 中加载C.class的类加载器不同!
类加载器的分类:
1、启动类加载器(Bootstrap ClassLoader) 这个类有c++语言实现,是虚拟机的一部分。
2、所有其他类加载器。其他类加载器都继承抽象类java.lang.ClassLoader。
做为java的大部分项目,都是有以下三类类加载器加载的:
1、启动类加载器。加载的内容为:<JAVA_HOME/lib 目录中的jar包。
2、扩展类加载器。加载的内容为:java.ext.dirs 系统变量指定的路径中所有类库。实现为:sun.misc.Launcher$ExtClassLoader 实现。
3、应用类加载器。实现为:sun.misc.Launcher$AppClassLoader。负责加载用户类路径上指定的类库。
下面我们看个例子:
此时如果大家到Test.java 所在的目录,执行javac Test.java 会报错:
为什会报错,因为org.apache.commons.lang.StringUtils 找不到,当前AppClassLoader 找不到StringUtils 类的路径。
找到StringUtils 可以通过指定-classpath .;D:\DevPlatform\m2localRepository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar 来找到。
大家注意到输出:
sun.misc.Launcher$AppClassLoader@19821f
sun.misc.Launcher$AppClassLoader@19821f
file:/E:/spring/spring-aop-aspectj/target/test-classes/
file:/E:/spring/spring-aop-aspectj/target/test-classes/
java.io.BufferedInputStream@1fb8ee3
java.io.BufferedInputStream@61de33
Test.class 和StringUtils.class 都是通过同一个类加载器(AppClassLoader)加载的。另外 通过Test.class.getResourceAsStream("/jdbc.xml") 找到了jdbc.xml 文件,jdbc.xml 文件在E:\spring\spring-aop-aspectj\src\test\java 也即是我执行java 和 javac 的位置。
这说明:AppClassLoader 的根目录在执行环境的目录。
下一步我们演示通过ExtClassLoader 加载,即通过-Djava.ext.dirs=D:\DevPlatform\m2localRepository\commons-lang\commons-lang\2.5 来加载commons-lang-2.5.jar包。
从上面的输出我们看到Test.class 和 StringUtils.class 的类加载器不同了,另外 System.out.println(StringUtils.class.getResourceAsStream("/jdbc.xml")); //没有找到对应的资源文件
System.out.println(Test.class.getResourceAsStream("/jdbc.xml")) //找到了对应的资源文件
为什么StringUtils.class 找不到对应的资源文件了,因为getResourceAsStream 是通过委托对应的类加载器来加载的,"/jdbc.xml" 通过不同的类加载器来加载,对于的资源文件的位置是不同的。
我在commons-lang-2.5.jar 包所在目录创建com 并在其下建立jdbc.xml 文件,继续运行结果如下:
看到上面的输出,一切都不言而喻。
总结:
对于Class.getResourceAsStream("/*.*") 是通过委托给对应的ClassLoader来加载的,其对应的资源文件的根目录为:
ExtClassLoader: 为java.ext.dirs 指定的目录下的所以目录。优先使用相应jar包的路径对应的根目录。比如java.ext.dirs=/home/q/,那么其根目录为/home/q/*dir。
AppClassLoader: 执行java javac 命令的目录。
注意:AppClassLoader寻找跟资源文件优先使用java.ext.dirs 指定的资源文件,如果没有才会到 命令执行的目录下寻找。 另外java.ext.dirs 指定的资源文件 最好不要有多个重名的文件,否则将不确定使用的是哪一个。
验证留给大家吧
类加载器ClassLoader 便是其中非常重要的概念。
本文简单并演示Java类加载器的一些特点,不妥之处,敬请指出。
背景:
A.java 引用 了B.jar 中的一个文件,B.jar 包中的C.class 使用了C.class.getResourceAsStream("/jdbc.xml")获取资源文件。 B.jar 做一个独立的功能的工具,使用方只要提供对应的jdbc.xml 配置文件即可在dev qa prod 各个环境使用啦。
但是问题来了,在web下和java命令行情况下,jdbc.xml 文件放置的位置大不相同,因为web 和java命令下 B.jar 中加载C.class的类加载器不同!
类加载器的分类:
1、启动类加载器(Bootstrap ClassLoader) 这个类有c++语言实现,是虚拟机的一部分。
2、所有其他类加载器。其他类加载器都继承抽象类java.lang.ClassLoader。
做为java的大部分项目,都是有以下三类类加载器加载的:
1、启动类加载器。加载的内容为:<JAVA_HOME/lib 目录中的jar包。
2、扩展类加载器。加载的内容为:java.ext.dirs 系统变量指定的路径中所有类库。实现为:sun.misc.Launcher$ExtClassLoader 实现。
3、应用类加载器。实现为:sun.misc.Launcher$AppClassLoader。负责加载用户类路径上指定的类库。
下面我们看个例子:
package org.job.user; import org.apache.commons.lang.StringUtils; public class Test { public static void main(String[] args) { System.out.println(Thread.currentThread().getContextClassLoader()); System.out.println(StringUtils.class.getClassLoader()); System.out.println(StringUtils.class.getResource("/")); System.out.println(Test.class.getResource("/")); System.out.println(StringUtils.class.getResourceAsStream("/jdbc.xml")); System.out.println(Test.class.getResourceAsStream("/jdbc.xml")); } }
此时如果大家到Test.java 所在的目录,执行javac Test.java 会报错:
为什会报错,因为org.apache.commons.lang.StringUtils 找不到,当前AppClassLoader 找不到StringUtils 类的路径。
找到StringUtils 可以通过指定-classpath .;D:\DevPlatform\m2localRepository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar 来找到。
大家注意到输出:
sun.misc.Launcher$AppClassLoader@19821f
sun.misc.Launcher$AppClassLoader@19821f
file:/E:/spring/spring-aop-aspectj/target/test-classes/
file:/E:/spring/spring-aop-aspectj/target/test-classes/
java.io.BufferedInputStream@1fb8ee3
java.io.BufferedInputStream@61de33
Test.class 和StringUtils.class 都是通过同一个类加载器(AppClassLoader)加载的。另外 通过Test.class.getResourceAsStream("/jdbc.xml") 找到了jdbc.xml 文件,jdbc.xml 文件在E:\spring\spring-aop-aspectj\src\test\java 也即是我执行java 和 javac 的位置。
这说明:AppClassLoader 的根目录在执行环境的目录。
下一步我们演示通过ExtClassLoader 加载,即通过-Djava.ext.dirs=D:\DevPlatform\m2localRepository\commons-lang\commons-lang\2.5 来加载commons-lang-2.5.jar包。
从上面的输出我们看到Test.class 和 StringUtils.class 的类加载器不同了,另外 System.out.println(StringUtils.class.getResourceAsStream("/jdbc.xml")); //没有找到对应的资源文件
System.out.println(Test.class.getResourceAsStream("/jdbc.xml")) //找到了对应的资源文件
为什么StringUtils.class 找不到对应的资源文件了,因为getResourceAsStream 是通过委托对应的类加载器来加载的,"/jdbc.xml" 通过不同的类加载器来加载,对于的资源文件的位置是不同的。
我在commons-lang-2.5.jar 包所在目录创建com 并在其下建立jdbc.xml 文件,继续运行结果如下:
看到上面的输出,一切都不言而喻。
总结:
对于Class.getResourceAsStream("/*.*") 是通过委托给对应的ClassLoader来加载的,其对应的资源文件的根目录为:
ExtClassLoader: 为java.ext.dirs 指定的目录下的所以目录。优先使用相应jar包的路径对应的根目录。比如java.ext.dirs=/home/q/,那么其根目录为/home/q/*dir。
AppClassLoader: 执行java javac 命令的目录。
注意:AppClassLoader寻找跟资源文件优先使用java.ext.dirs 指定的资源文件,如果没有才会到 命令执行的目录下寻找。 另外java.ext.dirs 指定的资源文件 最好不要有多个重名的文件,否则将不确定使用的是哪一个。
验证留给大家吧
发表评论
-
垃圾回收算法详解
2017-05-17 16:42 450可回收对象的判定【收藏,非原创】 讲算法之前,我们先要 ... -
垃圾回收算法&STOP The World
2017-05-15 11:50 619目前所有的新生代gc都是需要STW的: Seria ... -
java-jvm-jhat
2017-05-14 21:04 513功能:可以分析jmap dump下的hprof文件 一般 ... -
java-jvm-jinfo
2017-05-14 20:57 645jinfo: 1、输出 当前java进程启动的相关配置信息 ... -
jvm-gc 日志解读【转载】
2017-05-14 17:34 438转载自:http://ifeve.com/useful-j ... -
大量异常带来性能的影响
2017-05-09 19:08 635感受大量构造异常带来的性能影响: package com; ... -
iotop&iostat (load高 IO高的问题排查)
2017-04-27 20:40 2039目标:使用iotop&top&jstack ... -
java-jvm-jstack-(监视器和锁的概念)
2017-04-06 16:52 6421下面这段jstack的栈信息里,有一个死锁 其中: T ... -
java-jvm-jstack-线程状态
2017-03-31 14:42 2523常见的线程状态: RUNNABLE:正在执行的线程 注 ... -
java-jvm-cpu (cpu)高问题排查
2017-03-28 21:07 32891、通过top命令发现 cpu高的进程 根据top命令, ... -
java-jvm-jstack
2016-08-05 11:07 2157jstack用于打印出给定的java进程ID或core fi ... -
java-jvm好文收集
2016-08-05 10:50 385非常详细GC学习笔记http://blog.csdn.ne ... -
java-jvm-jstat
2016-08-05 10:30 596stat用于监控基于HotSpot ... -
java-jvm-jmap(高内存排查)
2016-07-29 13:51 3753功能:打印出某个java进程(使用pid)内存内的,所有‘对象 ... -
java-jvm-jps
2016-07-29 13:42 421jsp -q 只显示pid,不显示class名称,jar文件 ... -
OutOfMemoryError溢出
2016-03-29 23:29 795Java堆溢出: java.lang.OutOfMemor ... -
垃圾回收器的分类
2016-03-29 22:23 683基础: 串行收集器: DefNew:是使用-XX:+UseSe ... -
ClassLoader-线程上下文类加载器
2015-04-16 10:54 1113线程上下文类加载器 :http://blog.csdn.net ... -
ClassLoader-热替换
2015-04-05 20:27 2672https://www.ibm.com/developer ... -
ClassLoader-学习
2015-04-05 19:03 1018相关文章:https://www.ib ...
相关推荐
下面小编就为大家带来一篇classloader类加载器_基于java类的加载方式详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
处理配置文件对于Java程序员来说再常见不过了,不管是Servlet,Spring,抑或是Structs,都... 在了解了Java加载资源文件的机制后,以上这两个问题便迎刃而解了。 对于第一个问题,答案是:请将你的资源文件放在c
ClassLoaderTest 测试自定义的URLClassLoader以加载类 测试如何正确关闭类加载器。 测试如何使用反射关闭JarFile来修复资源泄漏。
class文件通常由类加载器(ClassLoader)来完成加载;class的执行在Sun JDK中有解释执行和编译为机器码执行两种方式,其中编译为机器码又分为client和server两种模式。Sun JDK为了提升class的执行效率,对于解释执行...
但是src/main/resources等资源目录只有在Eclipse项目重载时才会反映在target/classes ,所以如果在Eclipse外编辑资源文件,每次都需要重载Eclipse项目... 如果找到的 Java 类文件以外的资源位于target/classes ,...
Tomcat 内部定义了多个 ClassLoader,以便应用和容器访问不同存储库中的类和资源,同时达到应用间类隔离的目的。 1. Java 类加载机制 类加载就是把编译生成的 class 文件,加载到 JVM 内存中(永久代/元空间)。 类...
2、InputStream is = classLoader.getResourceAsStream("文件路径/文件名");//通过当前线程的类加载器获取流对象,如果是源文件夹,直接文件名 建议用当前线程类的加载器方式获取流,线程安全问题 ...
2、支持在插件中通过R文件使用宿主程序中的资源,暂不支持插件资源文件中直接使用宿主程序中的资源。但是支持间接使用。 例如在上述“已支持的功能”6中描述的,实际就是间接使用。 后续需要解决的问题: ...
通过虚拟目录获取文件资源 VirtualFile testFile = home.getChild("test.txt"); ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver....
最近做一些Android方面的优化工作,大家知道Android的ClassLoader在加载dex文件的过程中,而AndroidManifest的Application类就在dex文件中,Application通常会做一些全局的初始化工作,在加载dex之前,我们需要替换...
包括用于构建文件的向导(检查发行版,jCrypt.jar)。 Bin.jar必须位于jCrypt.jar的工作目录中 对输入档案进行加密,并将其写入Bin.jar的副本中,并在Extra字段中设置加密密钥,初始化向量,加密资源和mainclass。 ...
chapter15 反射与类加载器 499 15.1 运用反射 500 15.1.1 class与.class文档 500 15.1.2 使用class.forname() 502 15.1.3 从class获得信息 503 15.1.4 从class建立对象 506 15.1.5 操作对象方法与成员 ...
从Jar文件中动态加载类 ] () [ Java并发源码分析 - ThreadPoolExecutor ] () [ java ClassLoader 基本原理 ] () [ 解决eclipse显示jar源代码中文乱码问题 ] () [ 使用 RMI + ZooKeeper 实现远程调用框架 ] () [ Java...
3.3.2 资源加载 3.4 BeanFactory和ApplicationContext 3.4.1 BeanFactory介绍 3.4.2 ApplicationContext介绍 3.4.3 父子容器 3.5 Bean的生命周期 3.5.1 BeanFactory中Bean的生命周期 3.5.2 ApplicationContext中Bean...
3.3.2 资源加载 3.4 BeanFactory和ApplicationContext 3.4.1 BeanFactory介绍 3.4.2 ApplicationContext介绍 3.4.3 父子容器 3.5 Bean的生命周期 3.5.1 BeanFactory中Bean的生命周期 3.5.2 ApplicationContext中Bean...
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 13、sleep() 和 wait() 有什么区别? sleep是线程类(Thread)的...
37.classloader中,JDK的API、Classpath中的同web-inf中的class加载方式有什么区别? 38.列举三种以上垃圾回收算法,并比较其优缺点? 39.编写代码实现一个线程池 40.描述一下JVM加载class文件的原理机制? 41....
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 16、sleep() 和 wait() 有什么区别? sleep是线程类(Thread)...
轻量级Java插件框架1.特点简单的API 使用自定义Java类加载器进行沙箱测试使用Maven构建插件2.用法2.1创建插件创建实现ljpf.Plugin接口的... }} 为相应的插件创建描述符文件,并将其放置在项目资源中。 描述符文件必须具
25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................