class.getClassLoader().getResourceAsStream(file)和class.getResourceAsStream(file),都是实现获取在classpath路径下的资源文件的输入流。
项目目录
D:\demo1\src
│
├─main
│ ├─java
│ │ ├─com
│ │ │ └─example
│ │ │ └─demo
│ │ │ DemoApplication.java
│ │ │
│ │ └─META-INF
│ │ MANIFEST.MF
│ │
│ └─resources
│ │ application.properties
│ │
│ └─conf
│ dbcpconfig.properties
│
└─test
└─java
└─com
└─example
└─demo
DemoApplicationTests.java
编译后D:\demo1\out\artifacts\demo1_jar\demo1.jar文件目录
D:.
│ application.properties
│
├─com
│ └─example
│ └─demo1
│ Demo1Application.class
│
└─conf
dbcpconfig.properties
我们可以对比一下,conf文件夹编译前后的位置。
class是指当前类的class对象,getClassLoader()是获取当前的类加载器,什么是类加载器?简单点说,就是用来加载java类的,类加载器负责把class文件加载进内存中,并创建一个java.lang.Class类的一个实例,也就是class对象,并且每个类的类加载器都不相同。getResourceAsStream(path)是用来获取资源的,而类加载器默认是从classPath下获取资源的,因为这下面有class文件吗,所以这段代码总的意思是通过类加载器在classPath目录下获取资源.并且是以流的形式。
我们知道在Java中所有的类都是通过加载器加载到虚拟机中的,而且类加载器之间存在父子关系,就是子知道父,父不知道子,这样不同的子加载的类型之间是无法访问的(虽然它们都被放在方法区中),所以在这里通过当前类的加载器来加载资源也就是保证是和类类型同一个加载器加载的。
1、class.getClassLoader().getResourceAsStream(String name)
它默认从classpath中找文件(文件放在resources目录下),name不能带”/”,否则会抛空指针
eg:
InputStream stream = hread.currentThread().getContextClassLoader().getResourceAsStream("dbcpconfig.properties");
2、class.getResourceAsStream(String name)
它通过给定名称查找资源,查询资源的规则由给定的类的class load来实现,这个方法由类的loader来执行;如果这个类由bootstrap加载,那么方法由ClassLoader.getSystemResourceAsStream代理执行。 代理之前,绝对的资源名称通过传入的name参数以下算法进行构造: 如果name以”/”开头,那么绝对路径是/后边跟的名字。
eg:
//从classpath下的config相对路径中读取config.ini"
mypackage.Hello.class.getResourceAsStream("/config/config.ini");
如果name不是以”/”开头,那么绝对路径是package名”.”换成”/”以后再加name。
eg:
//com.abc.App就是/com/abc/App/name
//或者写作 :
../../name(以class所在路径为基准,文件相对于该类的路径)