`

java中ClassLoader加载资源

    博客分类:
  • java
阅读更多
加载资源可以用绝对路径和相对路径,但都有局限性。用硬编码的方式不好。

比较好的方式是绝对+相对方式。即绝对路径就是应用程序安装的路径,相对路径是资源文件相对于程序根目录的路径。

java.lang.ClassLoader不仅可以加载类到内存中,还可以加载其它的资源。

1. ClassLoader.getResourceAsStream

比方说配置文件,很多时候都是放在源代码路径下的,这样就可以直接使用ClassLoader

package com.john.basis;

public class MyClass {

InputStream inputStream = MyClass.class.getClassLoader().getResourceAsStream("com/john/basis/conf.properties");

}

这里的conf.properties是放在com.john.basis包下的,编译的时候IDE会帮我们把资源文件拷贝到生成目录。

ClassLoader的getResourceAsStream的操作分成两个部分:getResource()和openStream()。
getSystemResourceAsStream亦是如此。

下面就以getResourceAsStream为例:

public abstract class ClassLoader {

	public InputStream getResourceAsStream(String name) {
		URL url = getResource(name);
		try {
	    		return url != null ? url.openStream() : null;
		} catch (IOException e) {
	    		return null;
		}
	}

	public URL getResource(String name) {
		URL url;
		if (parent != null) {
	    		url = parent.getResource(name);
		} else {
			url = getBootstrapResource(name);
		}
		if (url == null) {
			url = findResource(name);
		}
		return url;
	}
	
	// Sub classes need to override this method
	protected URL findResource(String name) {
		return null;
	}
}

如果parent存在,则从parent中getResource();否则从启动引导路径中去找。
如果url还是null,则调用自定义的findResource()去找。

2. Class.getResourceAsStream

jdk帮我们简化了上面的代码,如果conf.properties是和MyClass在同一个目录下,那么可以直接调用类的getResourceAsStream方法:

InputStream inputStream = MyClass.class.getResourceAsStream("conf.properties");

其实Class类的getResourceAsStream(name)也是调用了ClassLoader.getResourceAsStream(name)方法的:

     public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);
    }

如果当前的ClassLoader为null,就调用ClassLoader.getSystemResourceAsStream(name)方法。

这里对name进行了预处理:
    private String resolveName(String name) {
        if (name == null) {
            return name;
        }
        if (!name.startsWith("/")) {
            Class c = this;
            while (c.isArray()) {
                c = c.getComponentType();
            }
            String baseName = c.getName();
            int index = baseName.lastIndexOf('.');
            if (index != -1) {
                name = baseName.substring(0, index).replace('.', '/')
                    +"/"+name;
            }
        } else {
            name = name.substring(1);
        }
        return name;
    }

如果name不是以'/'开头:
  替换包名中的.为/,将处理后的字符串作为前缀加到name上去。在这里就是:"com/john/basis" + "/" + "conf.properties"

否则,认为该文件存放在代码根目录,去除首字符'/'。
分享到:
评论
2 楼 czj4451 2013-06-02  
ClassLoader的getResource()方法的返回值就是java.net.URL类型啊。
1 楼 劳黑炭 2013-05-29  
我读取的内容需要以url形式,怎么从inputStream转为URL

相关推荐

    classloader类加载器_基于java类的加载方式详解

    下面小编就为大家带来一篇classloader类加载器_基于java类的加载方式详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Java加壳源码-自定义类加载器

    Java加壳核心代码,请调试后使用。本资源配合博客进行讲解,博客地址:http://blog.csdn.net/JavaBuilt/article/details/79522837

    Java加载资源文件的两种方法

    处理配置文件对于Java程序员来说再常见不过了,不管是Servlet,Spring,抑或是Structs,都...  在了解了Java加载资源文件的机制后,以上这两个问题便迎刃而解了。  对于第一个问题,答案是:请将你的资源文件放在c

    ClassLoaderTest:测试如何正确关闭类加载器,以便可以关闭基础jar文件上的文件句柄

    ClassLoaderTest 测试自定义的URLClassLoader以加载类 测试如何正确关闭类加载器。 测试如何使用反射关闭JarFile来修复资源泄漏。

    JAVA面试题,Java是一种面向对象的编程语言,由Sun Microsystems公司(现属Oracle公司)于1995年推出

    答:ClassLoader是Java虚拟机的一个组成部分,它负责加载Java类和资源。ClassLoader根据类的全限定名来查找并加载类。 4. 什么是Package? 答:Package是Java语言的命名空间机制,它用于组织类和接口。通过包可以避免...

    Java常用基础知识-kaic.docx

    今天我们进入《Java常用基础知识》专题,动力节点Java资源库整合了近年各大厂的面试中的常见问题和知识点。每天更新10个,我们的最终目标就是大厂,若对题目有疑问,可在公众号后台留言提问。 目标:阿里巴巴、腾讯...

    走出ClassLoader误区

    本资源主要介绍,类加载器是怎样对类进行加载的!并且类加载遇到的一些问题,方便架构师开发框架时,更多关于框架稳定性奠定了基础

    indexed-classloader:一个自定义的 JVM 类加载器,它索引类路径元素以获得更快的类资源位置

    构建: ./make-jar.sh 要使用,将indexed-classpath.jar添加到类路径并设置-Djava.system.class.loader=org.pantsbuild.classloader.IndexedURLClassLoader 。 添加-verbose:class以查看来自类加载器的调试信息。

    Java基础知识点.html

    类加载器 ClassLoader 反射 Stream 流 函数式编程 Lambda 表达式 网络编程-协议 网络编程-端口 网络编程-IP 多线程 IO流-字节流 IO流-字符流 IO流-转换流 File Map HashMap 序列化和反序列化 可变参数 类型通配符 ...

    JAVA面试题最全集

    37.classloader中,JDK的API、Classpath中的同web-inf中的class加载方式有什么区别? 38.列举三种以上垃圾回收算法,并比较其优缺点? 39.编写代码实现一个线程池 40.描述一下JVM加载class文件的原理机制? 41....

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

    必须要时从Java SE API的源代码分析,了解各种语法在Java SE API中如何应用。  《Java JDK 7学习笔记》将IDE操作纳为教学内容之一,使读者能与实践结合,提供的视频教学能更清楚地帮助读者掌握操作步骤。 内容简介 ...

    java 面试题 总结

    forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。 redirect...

    高级java笔试题-itresource:程序开发技术资源集合

    从Jar文件中动态加载类 ] () [ Java并发源码分析 - ThreadPoolExecutor ] () [ java ClassLoader 基本原理 ] () [ 解决eclipse显示jar源代码中文乱码问题 ] () [ 使用 RMI + ZooKeeper 实现远程调用框架 ] () [ Java...

    JVM中编译Class、内存回收、多线程原理和使用

    JVM负责装载class文件并执行,因此,首先是JDK如何将Java代码编译为class文件、如何...JVM提供了多线程支持,对于分布式Java应用而言,通常要借助线程来实现高并发,JVM中线程资源如何同步的机制及线程之间交互的机制。

    积分管理系统java源码-PluginActivityDemo:Hook方式实现Activity插件化

    积分管理系统java源码 Hook方式实现Activity插件化 随着应用程序的功能模块越来越多,...插件化的知识体系还是比较多的,包括Java反射原理,ClassLoader加载Dex原理,Android资源的加载,四大组件的加载,Android系

    Tomcat 类加载器的实现方法及实例代码

    Tomcat 内部定义了多个 ClassLoader,以便应用和容器访问不同存储库中的类和资源,同时达到应用间类隔离的目的。 1. Java 类加载机制 类加载就是把编译生成的 class 文件,加载到 JVM 内存中(永久代/元空间)。 类...

    eclipse-project-loader:ClassLoder 用于Eclipse项目中资源文件的高效引用

    Eclipse 项目加载器一个用于随时加载 Eclipse 项目资源而无需重新加载项目的 ClassLoader。 它可以通过在Eclipse的调试配置中指定-Djava.system.class.loader=...

    day020-继承加强和设计模式代码和笔记.rar

    即当前类所在路径及其引用的第三方类库的路径,如第四节中的问题6所述)下的类库 加载到内存中。 开发者可以直接使用系统类加载器。 5. 设计模式:(框架中使用,是程序设计的高级思想) 1. 单例模式...

    超级有影响力霸气的Java面试题大全文档

     forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。...

    jcrypt:加密的内存Classloader loader + Builder

    运行后,它将在Extra字段中加载信息,解密并加载包含加密的JAR的条目,然后调用它。 格式 Encrypt(K,I):使用对称密钥加密 P:目标JAR K:对称密钥 I:IV代表K C:资源加密布尔 将P作为Encrypt(K,I)存储在...

Global site tag (gtag.js) - Google Analytics