此文已由作者易国强授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

传统的properties读取方式

  • 一般的,我们都可以自定义一个xxx.properties文件,然后在工程的xml配置文件中注入相关的配置bean,示例如下:

    <context:property-placeholder location="classpath:config/${spring.profiles.active:unknown}/zk.properties" order="1" ignore-unresolvable="true" ignore-resource-not-found="true"/><bean id="kafkaProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean" ><property name="ignoreResourceNotFound" value="true"/><property name="location" value="classpath:config/${spring.profiles.active:unknown}/kafka.properties"/><property name="fileEncoding" value="UTF-8" /></bean>
  • 然后就可以在我们需要使用的地方之间使用xxx.properties中配置的信息。在Java和xml中使用示例分别如下:

    @Servicepublic class KafkaHotPostConsumer {@Value("#{kafkaProps['light.kafka.bootstrap.servers']}")
    private String KAFKA_BOOTSTRAP_SERVERS;
    <dubbo:registry id="faDataCenter" protocol="zookeeper" address="${zookeeper.servers}" group="${zookeeper.group.dataCenter}"/><bean id="kafkaClientL"class="com.netease.mq.kafka.KafkaProduerClient"><property name="level" value="low"></property><property name="brokerList" value="#{kafkaProps['light.kafka.bootstrap.servers']}"></property></bean>
  • 当然我们也可以针对某一个特定的配置文件,编写操作的PropertiesUtil类来进行操作,在此不再展开。

Spring Boot的properties读取方式

  • 在Spring Boot中对于配置文件的读取方式比较灵活,分别演示如下。

  • application.properties

    • 这个配置文件是默认的核心配置文件,原则上来说,如果有需要配置的信息可以直接存放在这里,不建议自定义配置文件存放,这样可以达到方便快速使用的目的。对于此配置文件下的信息读取非常简单,如果是在配置文件中需要获取已定义的信息,则可直接使用,如下所示:

      #服务启动端口server.port=7777#自定义字段custom.url=http://localhost:${server.port}/query.do
    • 在Java代码中使用也非常简单,可以通过@Value注解或者通过Environment类来获取当前环境中加载的配置信息,示例如下:

      @Value("${server.port}")private String port;@AutowiredEnvironment env;@GetMapping("/")public String hello(){System.out.println("my server port is =" + port);System.out.println("custom url = " + env.getProperty("custom.url","defaultValue"));  return "hello,world";
      }
  • 当然,如果我们需要自定义properties文件来存取我们想要的信息也是支持的。实际上,不论是application.properties还是自定义的demo.properties文件,最终都会转化映射一个具体的配置类,而我们实际上在代码中操作的就是这个配置类。下面我们演示下如何自定义配置文件。

    • 新建配置文件demo.properties,如下所示:

      demo.username=demo
      demo.email=demo@163.com
    • 然后编写对应的映射类,如下所示,实际上,上面也有介绍,我们也可以使用@Value注解获取配置信息,不过用environment的方式获取,可以指定默认值。这里我们需要注意加入@Configuration的注解,然后指定对应的配置文件路径即可。

      import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import org.springframework.core.env.Environment;/**
      * 演示自定义配置文件读取
      * <p>
      *
      * @date 2017/10/18 10:57.
      * @author bjyiguoqiang
      */@Configuration@PropertySource("classpath:demo.properties")public class DemoProperties {  @AutowiredEnvironment environment;  public String getUsername() {      return environment.getProperty("demo.username");}  public String getEmail() {      return environment.getProperty("demo.email");}
      }
    • 接下来我们就可以直接操作DemoProperties这个类来读取配置信息了。示例如下:

      @ResourceDemoProperties demoProperties;
      ....../**
      * 1、核心配置文件的读取示例
      * </p>
      * 2、自定义配置文件的读取示例
      *
      * @return*/@GetMapping("/")public Object hello() {  //读取自定义配置文件String email = demoProperties.getEmail();String username = demoProperties.getUsername();logger.info("demo properties : email={},username={}", email, username);
      }
  • 当然我们也可以在启动程序jar的时候指定外部的配置文件,如果程序在启动时就会优先加载外部的这个配置文件,示例如下:

java -jar demo.jar --spring.config.location=/opt/config/application.properties

遇到的问题

  • 正常情况下,通过上面列举的读取方式基本能满足我们的使用需求,但也存在特殊的情况。比如我们很多场景还是会引入第三方的jar包或需要自己封装jar包来提供给其他服务使用,那么这个时候不能强依赖spring boot框架的读取方式。

  • 如果在我们的jar包需要获取某一特定的配置文件中的信息该怎么办呢?这里就需要注意了,不然就会掉进坑里。这也是我们实际遇到的一个问题,原来在代码中读取配置文件代码示例如下:

BufferedInputStream in = null;
URL resourceFile = Thread.currentThread().getContextClassLoader().getResource("/demo.properties");String path = resourceFile.getPath();try {    in = new BufferedInputStream(new FileInputStream(path));
} catch (FileNotFoundException e) {   //.....}PropertyResourceBundle resource = null;try {resource = new PropertyResourceBundle(in);
} catch (IOException e) {    //.....}
HashMap props = new HashMap();
Iterator uriArray = resource.keySet().iterator();String strTmp;while(uriArray.hasNext()) {strTmp = (String)uriArray.next();props.put(strTmp, resource.getObject(strTmp));
}String demoEmail  = (String)props.get("demo.email");
  • 上面的代码在非Spring Boot项目中运行是没有什么问题的,我们只需要在resources下存放demo.properties文件即可正常读取。但在spring boot项目中读取却会出现问题。抛出的错误很直观,就是提示在classpath下找不到对应的文件。

  • 出现问题的根本原因在于Spring Boot 如果以jar包的形式进行部署,classpath路径会被替换成jar:file:/xxx/xxx/classess!,最终生成的资源路径为jar:file:/xxx/xxx/classess!/xx/xx.xx

  • 因为服务是通过jar包启动的,通过系统的文件系统并不能获取到我们想要的文件(比如demo.propeties),所有使用诸如new File(path)的形式就会出现问题

  • 我们可以变更以流的方式读取来获取jar中的类资源文件。示例代码如下:

//直接返回StreamInputStream inputStream  = Thread.currentThread().getContextClassLoader().getResourceAsStream("demo.properties");
BufferedInputStream in  = new BufferedInputStream(inputStream);
PropertyResourceBundle resource = null;try {resource = new PropertyResourceBundle(in);
} catch (IOException e) {    //.....}
HashMap props = new HashMap();
Iterator uriArray = resource.keySet().iterator();String strTmp;while(uriArray.hasNext()) {strTmp = (String)uriArray.next();props.put(strTmp, resource.getObject(strTmp));
}String demoEmail  = (String)props.get("demo.email");

最后

  • 通过上面所述,结合大家亲自实践后,应该不难发现Spring Boot提供的配置文件读取更加的灵活强大,也符合框架本身快速开发的思想。

  • 不足之处,欢迎指正,谢谢~

免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击。

相关文章:
【推荐】 中秋福利|10本技术图书(编程语言、数据分析等)免费送
【推荐】 Android中Textview显示Html,图文混排,支持图片点击放大
【推荐】 Android View部分消失效果实现

转载于:https://www.cnblogs.com/163yun/p/9884675.html

Spring Boot 学习系列(07)—properties文件读取相关推荐

  1. Spring Boot 学习系列(01)—从0到1,只需两分钟

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 快速构建 如果我们想基于spring mvc 提供一个简单的API查询服务,传统的方式,首先需要我们引入sp ...

  2. Spring Boot 学习系列(05)—自定义视图解析规则

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 自定义视图解析 在默认情况下Spring Boot 的MVC框架使用的视图解析ViewResolver类是C ...

  3. Spring Boot 学习系列(04)—分而治之,多module打包

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 明确功能,各司其职 在一个结构清晰的项目中,一个没有module划分的结构显然不是最佳实践.有人会说可以在同 ...

  4. Spring Boot 学习系列(09)—自定义Bean的顺序加载

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Bean 的顺序加载 有些场景中,我们希望编写的Bean能够按照指定的顺序进行加载.比如,有UserServ ...

  5. Spring Boot 学习系列(08)—自定义servlet、filter及listener

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 传统的filter及listener配置 在传统的Java web项目中,servlet.filter和li ...

  6. Spring Boot 学习系列(02)—使用热部署,提升开发效

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 开发调试很简单 热部署的使用非常简单,但能极大的提高我们的开发效率,像传统的web应用,我们修改后需要重新编 ...

  7. 2023最新首发,全网最全 Spring Boot 学习宝典(附思维导图)

    作者:bug菌 博客:CSDN.掘金.infoQ.51CTO等 简介:CSDN/阿里云/华为云/51CTO博客专家,博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,掘金/ ...

  8. Spring Boot干货系列:(六)静态资源和拦截器处理 | 掘金技术征文

    原本地址:Spring Boot干货系列:(六)静态资源和拦截器处理 博客地址:tengj.top/ 前言 本章我们来介绍下SpringBoot对静态资源的支持以及很重要的一个类WebMvcConfi ...

  9. Spring Boot实战系列《六》:人事管理系统的登录设计

    Spring Boot实战系列<六>:人事管理系统的登录设计 Spring Boot实战系列<六>:人事管理系统的登录设计 1.前言 在上一篇中教大家在IEDA或者eclips ...

最新文章

  1. Ubuntu中安装docker-compose
  2. JDBC-day01
  3. 【杂谈】有三AI专业版学习扑克牌上线,一副扑克,看懂AI核心技术
  4. mac设置截图和录屏的快捷键
  5. epoll 边沿触发 非阻塞 IO 服务器
  6. 官宣|Apache Flink 1.13.0 正式发布,流处理应用更加简单高效!
  7. (30)css3动画
  8. 控制流图|圈复杂度|基本复杂度
  9. DRBD详细解说及配置过程记录
  10. 用户没有create session权限_快速搞懂Oracle 19c安全新特性 (二)Privilege Analysis(权限分析)...
  11. Failed to start The nginx HTTP and reverse proxy server.
  12. vue给标签动态添加元素_vue中用v-html加载html元素及三种方法给v-html元素添加样式(详解)...
  13. 必杀VI、VIM编辑器命令
  14. mysql定义取值范围_mysql的decimal类型取值范围
  15. 快速文件扫描王用户协议
  16. STM32F411RE Nucleo笔记-按键控制PWM占空比
  17. git lfs官网翻译
  18. 项目 6 统计雇员薪水
  19. day10 爬虫导言
  20. 初学orCAD原理图

热门文章

  1. 在Android上可视化TensorFlow Lite AI结果
  2. 阿里云、蚂蚁开源 Nydus——容器镜像加速服务
  3. Vue学习笔记(四)—— 前端路由
  4. 简易 Vue 构建--篇二
  5. linux版本的redis bin,redis-4.0.2.tar.gz for centos的linux系统版本下载(安装详细步骤)...
  6. Referenced file contains errors (http://www.springframework.org/schema/context/spring-context-3.1.xs
  7. linux调整网页视频声音,网络学员面试常见问题请你修改一下LINUX的视频驱动和声音.DOC...
  8. java this()函数_java中this关键字的三种用法
  9. 7-43 币值转换 (20分)_「篮球看吧」40岁了!生涯25年!还狂砍33分+联赛得分王,这他么是人吗...
  10. qt android刘海屏状态栏,华为Mate30 Pro设计曝光:仍配刘海屏+3D结构光