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

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

传统的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 {  @Autowired
        Environment 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部分消失效果实现

Spring Boot 学习系列(07)—properties文件读取的更多相关文章

  1. 【Spring源码分析】.properties文件读取及占位符${...}替换源码解析

    前言 我们在开发中常遇到一种场景,Bean里面有一些参数是比较固定的,这种时候通常会采用配置的方式,将这些参数配置在.properties文件中,然后在Bean实例化的时候通过Spring将这些.pr ...

  2. Spring Boot 学习系列(10)—SpringBoot+JSP的使

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 解决问题 随着spring boot 框架的逐步使用,我们期望对于一些已有的系统进行改造,做成通用的脚手架, ...

  3. Spring Boot 学习系列(06)—采用log4j2记录日志

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 为什么选择log4j2 log4j2相比于log4j1.x和logback来说,具有更快的执行速度.同时也支 ...

  4. Spring Boot 学习系列(03)—jar or war,做出你的选择

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 两种打包方式 采用Spring Boot框架来构建项目,我们对项目的打包有两种方式可供选择,一种仍保持原有的 ...

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

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

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

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

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

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

  8. Spring Boot 学习系列(序)—Spring Boot

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Spring Boot? Spring Boot 是由pivotal团队提供的一个基于Spring的全新框架 ...

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

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

随机推荐

  1. Mac终端处理MySql

    进入数据库: mysql -u root -p 随后输入密码:root   原文出处: GarveyCalvin的博客(@GarveyCalvin) MySQL有很多的可视化管理工具,比如“mysql ...

  2. Centos7-安装Apache2.4+PHP5.6

    linux系统CentOS7先下载Apache需要依赖的软件1.APR下载地址http://apr.apache.org/download.cgiwget下载路径http://mirror.bit.e ...

  3. lua 字符串处理

    匹配模式(pattern) . 任何单个字符 %a 任何字母 %c 任何控制字符 %d 任何数字 %g 任何除空白符外的可打印字符 %l 所有小写字母 %p 所有标点符号 %s 所有空白字符 %u 所 ...

  4. SQL查询刚開始学习的人指南读书笔记(三)值表达式

    CHAPTER 5 Getting More Than Simple Columns Intro Value  expression,it contains column names, literal ...

  5. erlang启动参数记录

    不管在erlang的shell下还是脚本里,启动参数都是非常有用的,抽空儿整理下erlang的常用启动参数: +A size   异步线程池的线程数,范围为0~1024,默认为10 +P Number ...

  6. 04 http协议模拟登陆发帖

    <?php require('./http.class.php'); $http = new Http('http://home.verycd.com/cp.php?ac=pm&op=s ...

  7. Python使用Mysql过程中一些错误

    Python使用Mysql过程中一些错误 ssh登录远程服务器 ssh ubuntu@xxx.xxx.xx.xx 第一:ubuntu终端中登录Mysql mysql -uroot -p 然后输入密码即 ...

  8. C#特性类的使用

    特性类的使用过程: 第一步:定义一个特性类,定义一些成员来包含验证时需要的数据:第二步:创建特性类实例:创建一个特性类的实例,里面包含着验证某一个属性或者字段需要的数据.将该实例关联到某个属性上面.第 ...

  9. 【BZOJ3782】上学路线 组合数+容斥+CRT

    [BZOJ3782]上学路线 Description 小C所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M).小C家住在西南角,学校在东北角.现在有T个路口进行施工,小C不 ...

  10. EasyDarwin接入ffmpeg实现264转图片快照功能

    本文转自:http://blog.csdn.net/cai6811376/article/details/51774467 EasyDarwin一直坚持开源精神,所以我们着手把EasyDarwin中使 ...