2021.3.28
问题描述
今天在学习尚硅谷小项目的时候看到老师写的代码中用到了
JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
这样一段代码,目的是为了加载jdbc.properties这个配置文件,但是我发现我自己使用的时候是空指针异常。非常莫名其妙。
于是乎,在网上找了一堆资料,发现很多人都在文章中推荐使用
Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties");
这个方法来读取配置文件。
理由真的五花八门:有说在JavaEE服务器中里面classpath路径跟JavaSE里面的不一样,也有说类加载器不一样的。
我一脸懵逼,但还是试了一下,发现居然还真可以。
但是我代码里面并没有涉及到服务器的东西,又怎么会有区别呢?
于是我尝试把这两种做法的类加载器都输出出来。
得到的结果,基本上是否认了网上说的一些类加载器不一样的说法,因为两个加载器都是一模一样的。
(他们的说法可能在部署了服务器的时候有效)
而此时我把代码重新用回了第一种加载器来进行加载properties文件,发现代码顺利执行了。
这就更加肯定了,我的这个问题并不在于这两个方法的区别上。
解决问题
观察文件目录结构
工程目录src/main/resources下的文件一般在编译后是会自动复制到target/classes目录下的。
但是也有例外的情况,IDEA有可能会自己抽风,并没有成功把resources中文件复制到classes对应的目录下。
这样,所以一开始无法读取成功的原因就是target的classes文件夹下缺少了这个properties文件。
验证
我把这个target的classes文件夹下的这个properties文件,删除后,分别用两个不同的方法来进行读取。都报空指针异常。
因此,我的问题并不在于这两个读取方法的区别上,而是在于classpath中缺失配置文件。
收获
- 尽管看了很多跟我这个问题并不扯上关系的资料,但是通过查阅资料了解到了在JavaEE部署上一般都用这种获取类加载器的方式来获得静态资源文件,而并非通过用户文件夹相对路径来查找。
- 这两个类加载器上确实有区别,网上资料中推荐使用Thread.currentThread().getContextClassLoader().getResourceAsStream(“jdbc.properties”)这种方法,提前知道,可以避免日后踩坑。
- classes文件夹其实就是技术资料所说的classpath。