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

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

传统的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. 深度解析开发项目之 01 - SVProgressHUD用法

    深度解析开发项目之 01 - SVProgressHUD用法 首先来到工程的pch文件中 01 - 导入头文件 02 - 定义宏 03 - 项目中的使用 3.1 - SVHUD_Normal:  3. ...

  2. 03 xml封装通信接口

    <?php class Response_xml{ /** *按xml方式输出通信 *@param integet $code 状态码 *@param string $message 提示信息 ...

  3. Android Material Design 中文版

    http://www.google.com/design/spec/animation/authentic-motion.html http://www.oschina.net/question/14 ...

  4. C# 调用类库里的事件

    首先在类库中定义事件: //定义委托 public delegate void DelWeiTuo(string name); //定义事件 public event DelWeiTuo EventW ...

  5. Ubuntu 13.10上用户怎样获得root权限,用户怎样获得永久root权限,假设配置root登录

    一.用户怎样获得root权限: 1. 进入terminal 2. 输入sudo  passwd root   并设置password,提示要你输入两次password.自己设定password,一定要 ...

  6. PHP收邮件receiveMail

    用PHP来发邮件,相信大家都不陌生,但读取收件箱的话,接触就少了,这次总结下自己的经验,希望能够帮助大家. 注意:1.PHP读取收件箱主要是利用imap扩展,所以在使用下面方法前,必须开启imap扩展 ...

  7. 【BZOJ3007】拯救小云公主 二分+几何+对偶图

    [BZOJ3007]拯救小云公主 Description     英雄又即将踏上拯救公主的道路……     这次的拯救目标是——爱和正义的小云公主.     英雄来到boss的洞穴门口,他一下子就懵了 ...

  8. EasyNVR将如何能够把内网各种各样的监控摄像机对接到公网云平台

    需求 传统监控行业里面,监控客户端.服务器端,设备端都在一个内网里面,搞个电脑开个监控终端,顶多再配一个NVR做一做摄像机的录像存储.上个电视墙(个人感觉这功能除了面子工程,没啥实用的,还特费电!), ...

  9. ZOJ 3551 Bloodsucker <概率DP>

    题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3551 题意:开始有N-1个人和一个吸血鬼, 每天有两个生物见面,当人 ...

  10. cerery

    cerery http://docs.celeryproject.org/en/latest/userguide/index.html