前言

相信很多人遇到过这个问题:本地运行的好好的程序,怎么部署到线上就报找不到配置呢?

初识getResource
案例一
  FieldMapConfig.class.getResource("p1.properties").getPath();
``` - 这段代码在本地运行没有任何问题,一放到线上就报空指针。 ###### 案例二 ![file](https://graph.baidu.com/resource/22243f231967f8c552ea801577605576.png) - 读取配置,报错FileNotFoundException。
- 乍一看,两段代码好像没有什么区别,但是细心的你,应该发现:

App.class.getClassLoader().getResource("p1.properties").getPath();

FieldMapConfig.class.getResource("p1.properties")

- 一个使用当前class的api,一个使用的当前class的classLoader的api来获取的,这有什么区别呢?请听我细细分说。

##### Class和ClassLoader

- 秉着探索的态度,我写了一个例子,请看:

public static void main( String[] args ) {

    if (args.length != 1) {
System.out.println("usage: java -jar com.hyq.simple-1.0.jar args");
return;
} System.out.println("App.class.getResource(args[0]):");
System.out.println(App.class.getResource(args[0]));
System.out.println(); System.out.println("App.class.getClassLoader().getResource(args[0]):");
System.out.println(App.class.getClassLoader().getResource(args[0]));
System.out.println(); System.out.println("App.class.getResourceAsStream(args[0]):");
System.out.println(App.class.getResourceAsStream(args[0]));
System.out.println(); System.out.println("App.class.getClassLoader().getResourceAsStream(args[0]):");
System.out.println(App.class.getClassLoader().getResourceAsStream(args[0]));
System.out.println(); }

- 验证如下: ![file](https://img2018.cnblogs.com/blog/894494/201912/894494-20191229171443615-244970716.jpg) - 从上图可以看出,使用当前类的GetResource和当前类的classloader的getResource,
获取到的配置有区别。怎么解释呢? 前者是读取的当前类的包目录下的配置文件 后者读取的是,jar包内部,根目录的配置文件。 总结:当读取配置的路径不是以/开头时,会按相对路径读取,相对的是当前类的class 这个文件,而采用class的classLoader则是相对于根路径(也就是我们说的classpath)。 ##### 各种路径试验 - 如果你还在为相对路径,配置文件前面带不带/,等一系列问题折腾,那不如动手做做试验看看,代码还是上面那段代码,通过动态传入配置文件的路径来读取,试验结果如下: ![file](https://img2018.cnblogs.com/blog/894494/201912/894494-20191229171443871-77831805.jpg) ##### 为什么推荐使用getResourceAsStream? - 形如:"jar:file:/data/simpleJava/com.hyq.simple-1.0.jar
!/p1.properties" 这样的路径,getResource是无法读取的,因为他不是一个文件路径。
而getResourceAsStream会以流的方式,打开文件来读取数据,上图的文件树,就是我用unzip命令解压jar包后显示出来的。 ##### springboot加载配置
默认情况下,springboot会加载名为application的properties或者yml文件。
其中查找的顺序为:
- 1、当前jar包所在目录的config目录下。
- 2、当前目录。
- 3、jar包内classpath的config目录。
- 4、jar包内classpath目录。 注意:重复定义的配置,会被后者覆盖。 ###### 通过名字动态加载配置? ###### 知识点一
- boot配置的语法是,凡是以--开头(两个横线)的配置,会被解析。
相信大家可能遇到过这样一个场景,同一个jar包要启动多次,每个进程的配置不一样,端口不同。 ![file](https://img2018.cnblogs.com/blog/894494/201912/894494-20191229171444257-525834636.jpg) ###### 知识点二
通过--spring.config.name 指定配置文件名即可。
还有一种新奇的方式,直接通过spring.application.json传递json,案例如下:

java -Dspring.application.json='{"name":"test"}' -jar myapp.jar


###### 知识点三
当然,你也可以指定多个配置文件,方式如下:

java -jar myproject.jar

--spring.config.location=classpath:/p1.properties,classpath:/p2.properties

值得注意的是,config配置文件搜索的顺序和指定的顺序是刚好相反的。

###### 知识点四
通过spring.profiles.active属性可以指定那个环境下的配置。 ![file](https://img2018.cnblogs.com/blog/894494/201912/894494-20191229171444449-2036003783.jpg)
这里我比较喜欢定义两个yml,然后在application.yml中指定对应环境的配置。

spring:

profiles:

active: prod

```

知识点五

可以通过@value注解来获取变量值

@Value("${app.init.welcome-msg:侠梦的开发笔记}")
private String msg;

也可以通过@ConfigurationProperties("app.init")注解,放在类来获取整个配置。

总结
  • 本章节我们做了实验,了解了getResource和getResourceAsStream的区别。
  • 学习了springboot通过动态指定配置名,读取配置。
  • 指定读取多个配置文件。
  • 不同运行环境获取不同配置的方式。

欢迎来公众号【侠梦的开发笔记】 一起交流进步

拒绝FileNotFoundException!总结了这几个读取jar包外配置文件的知识点的更多相关文章

  1. scala读取jar包外配置文件的方式

    在scala的开发过程中,经常会修改程序的参数,将这些参数放到配置文件中避免了重复编译,打包的过程 这里给出读取配置文件的三种方式 方式一: 这是最常见的读取配置文件方式 val postgprop ...

  2. 如何读取jar包外的properties文件和log4j.properties

    http://jrails.iteye.com/blog/1705464 ***************************************' 一般在项目中使用properties配置文件 ...

  3. 读取Jar包中的资源问题探究

    最近在写一个可执行jar的程序,程序中包含了2个资源包,一个是images,一个是files.问题来了,在Eclipse里开发的时候,当用File类来获取files下面的文件时,没有任何问题.但是当程 ...

  4. jar包读取jar包内部和外部的配置文件,springboot读取外部配置文件的方法

    jar包读取jar包内部和外部的配置文件,springboot读取外部配置文件的方法 用系统属性System.getProperty("user.dir")获得执行命令的目录(网上 ...

  5. 读取jar内的配置文件

    读取jar包内的配置文件,可以使用ResourceBundle,具体具体例子如下 import java.io.BufferedInputStream; import java.io.IOExcept ...

  6. 读取jar包里面的文件

    一.最近做项目的时候,师兄要求读取jar包里面的java文件.在网上查了各种文件以后,终于完成了,在这里和各位朋友分享一下. (一)找到jar包所在的位置. String path="XXX ...

  7. Jar中的Java程序如何读取Jar包中的资源文件

    Jar中的Java程序如何读取Jar包中的资源文件 比如项目的组织结构如下(以idea中的项目为例): |-ProjectName |-.idea/  //这个目录是idea中项目的属性文件夹 |-s ...

  8. springboot jar启动 读取jar包中相对路径文件报错

    jar包启动后读取相对路径文件报异常: Caused by: java.io.FileNotFoundException: class path resource [***.***] cannot b ...

  9. maven install 读取jar包时出错;error in opening zip file

    错误信息: [INFO] ------------------------------------------------------------------------ [ERROR] Failed ...

随机推荐

  1. js中的超过16位数字相加问题

    方案一 function sub(str1, str2) { // 补全0,并多补一位0 let arr1 = null, arr2 = null if (str1.length > str2. ...

  2. 自定义属性 —— data-*

    一.基本概念 在HTML5中添加了data-*的方式来自定义属性,所谓data-*实际上上就是data-前缀加上自定义的属性名,使用这样的结构可以进行数据存放.使用data-*可以解决自定义属性混乱无 ...

  3. 三 nginx+uWSGI+django+virtualenv+supervisor发布web服务器

    https://www.cnblogs.com/pyyu/p/9481344.html?tdsourcetag=s_pcqq_aiomsg 一 uwsgi安装 1.安装uwsgi,进入到一个虚拟机环境 ...

  4. 给图片加ALT属性是个什么意思?有什么优点呢

    使用百度统计的seo建议当中一条图片ALT信息"存在没有alt信息的img标签"扣分较多.站点图片中加入ALT对seo有什么优点呢?这是非常多初学seo的朋友们都须要询问的问题.a ...

  5. OpenCV 新手教程 之环境配置 + 图片匹配 matchTemplate

    1.什么是OpenCV OpenCV的全称是:Open Source Computer Vision Library. OpenCV是一个基于(开源)发行的跨平台计算机视觉库,能够执行在Linux.W ...

  6. MySql计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数

    MySql计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数 计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数,这里主要分享的是通过MySql内置的函数 TimeStampDiff() ...

  7. List<object> 转 List<T>

    List<TAXIWAY_CENTER_LINE> kk = allObjs.Where(c => c.ToString() == "AMXM.TAXIWAY_CENTER ...

  8. windows 下的 Apache 二级域名 目录绑定配置

    通常我们注册的域名都是顶级域名  如 www.potatog.com,我们希望这个域名可以访问服务器的不同网站或者不同功能等等 可能会这样 www.potatog.com/api 或者 www.pot ...

  9. 权重衰减(weight decay)与学习率衰减(learning rate decay)

    本文链接:https://blog.csdn.net/program_developer/article/details/80867468“微信公众号” 1. 权重衰减(weight decay)L2 ...

  10. Oracle/PLSQL存储过程详解

    原文链接:https://blog.csdn.net/zezezuiaiya/article/details/79557621 Oracle/PLSQL存储过程详解 2018-03-14 17:31: ...