一文理解:class.getClassLoader().getResourceAsStream(file) 和 class.getResourceAsStream(file)区别。未彻底看懂

一文理解

  • class.getClassLoader().getResourceAsStream(file)

  • class.getResourceAsStream(file)区别

  • https://blog.csdn.net/feeltouch/article/details/83796764

BOOT-INF

基础理解
都是实现获取在classpath路径下的资源文件的输入流。

为什么是classpath而不是src,因为当web项目运行时,IDE编译器会把src下的一些资源文件移至

  • WEB-INF/classes,classPath目录其实就是这个classes目录。
    • 这个目录下放的一般是web项目运行时的class文件、资源文件(xml,properties…);

另外,在使用springboot进行开发时,其目录默认不是WEB-INF而是

  • BOOT-INF,但是其含义是一样的。具体如下图所示:

img

上图,蓝框中即为classpath中的内容,也就是自己实际编写的代码,另外依赖的代码主要在lib目录下。

  • org
    • 类加载器和核心文件:org\springframework\boot\loader
  • META-INF
    • Maven文件
    • maven\com.example\demo-mp
  • BOOT-INF
    • \BOOT-INF\lib
    • \BOOT-INF\classes

再从另外一个视角对比下,编译前后文件所在目录的变化

编译前:

img

编译后:

img

需要的配置

  • 依然需要配置后,才会打包到这个目录下
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                    <include>**/*.yml</include>
                    <include>**/*.yaml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                    <include>**/*.yml</include>
                    <include>**/*.yaml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>

类加载器

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 = Thread.currentThread().getContextClassLoader().getResourceAsStream("gamvanclub.cfg.xml");
  1. class.getResourceAsStream(String name)

通过给定名称查找资源,查询资源的规则由给定的类的class load来实现,这个方法由类的loader来执行;如果这个类由bootstrap加载,那么方法由ClassLoader.getSystemResourceAsStream代理执行。

代理之前,绝对的资源名称通过传入的name参数以下算法进行构造:

如果name以"/"开头,那么绝对路径是/后边跟的名字

//从classpath下的config相对路径中读取config.ini"
mypackage.Hello.class.getResourceAsStream("/config/config.ini");

如果name不是以"/"开头,那么绝对路径是package名"."换成“/”以后再加name

eg:

//com.abc.App就是/com/abc/App/name 或者写作 : ../../name(以class所在路径为基准,文件相对于该类的路径)

Java类加载过程

3个步骤:

1.加载,加载类的二进制文件。

2.链接:

(1)验证,验证字节码的结构是否正确

(2)准备,给静态成员分配空间并赋予默认值

  • (注意这里:静态变量的第一次赋值是在类加载的时候就进行了,与后面初始化的时候的自定义赋值不是同一过程,也就是静态成员在初始化的时候可能已被赋值二次了)

    • 这里应该赋默认值

    (3)解析,将符号引用变为直接引用

3初始化,为静态成员赋予自己给定的初值

类的实例化的顺序:

(1)静态成员、方法与静态代码块的初始化与执行

(2)普通成员、方法与普通代码块的初始化与执行

(3)构造函数的执行(父类的构造函数先执行)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值