为什么 ClassLoader 类的 getResource(String name) 方法能够读取到原本在 src/main/resources 里面的文件?

为什么 ClassLoader 类的 getResource(String name) 方法能够读取到原本在 src/main/resources 里面的文件?

在 Java 开发中,ClassLoader 类是一个关键的组件,用于加载类和资源。其中,getResource(String name) 方法允许我们在类路径中查找指定名称的资源文件。一个常见的疑问是:为什么这个方法能够轻松地读取到Maven项目中src/main/resources目录下的文件呢?

1、类路径和资源文件

在Maven项目中,源代码通常存放在src/main/java目录下,而资源文件则存放在src/main/resources目录下。这样的组织结构是为了在构建过程中能够清晰地分离代码和资源。

在编译时,Maven将src/main/resources目录下的文件复制到类路径中,通常是target/classes目录。这意味着编译后,资源文件就变成了类路径的一部分。

2、ClassLoader 的层次结构

ClassLoader 类的设计支持层次结构,其中每个类加载器都有一个父类加载器。当类加载器需要加载类或资源时,它首先会尝试从父加载器中查找,然后再从自身的类路径中查找。

这机制为ClassLoader提供了一种委托机制,确保资源的查找是层次化的,逐级向上寻找,直至找到为止。

3、getResource 方法的工作原理

ClassLoadergetResource(String name) 方法实际上是利用了这一层次结构的委托机制。它首先尝试调用父加载器getResource 方法,如果父加载器找不到资源,再从自己的类路径中查找。这保证了在整个类加载器层次结构中,资源文件可以被有效地定位。

因此,当我们使用ClassLoadergetResource 方法时,它会顺着类加载器的层次结构,最终在编译后的类路径中找到src/main/resources目录下的文件。

4、使用 ClassLoader 类图示

image-20231121222446332

5、仅使用 FileInputStream (不推荐,也不合理)

该路径是相对路径,并且是相对于项目的根目录的。

这么写是不合理的!

image-20231121222654369