SpringBoot 教程 & 笔记 |Demo03- 配置文件

本贴最后更新于 2367 天前,其中的信息可能已经渤澥桑田

SpringBoot 是为了简化 Spring 应用的创建、运行、调试、部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖就可以轻易的搭建出一个 WEB 工程

SpringBoot 虽然干掉了 XML 但未做到 零配置,它体现出了一种 约定优于配置,也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。 一般情况下默认的配置足够满足日常开发所需,但在特殊的情况下,我们往往需要用到自定义属性配置、自定义文件配置、多环境配置、外部命令引导等一系列功能。不用担心,这些 SpringBoot 都替我们考虑好了,我们只需要遵循它的规则配置即可

准备前提

本教程在Demo02基础上添加配置信息

构建项目的时候,自动创建的是 application.properties 文件,我们重命名改成 application.yml

为了让 Spring Boot 更好的生成配置元数据文件,我们需要添加如下依赖(该依赖可以不添加,但是在 IDEA 和 STS 中不会有属性提示,但是引入这个包会有相应提示),该依赖只会在编译时调用,所以不用担心会对生产造成影响…

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>

添加依赖

自定义属性配置

application.yml 写入如下配置内容

test: age: 22 name: testUser

自定义属性配置

其次定义 src/main/java/com/heardfate/springboot/demo/properties/MyTestProperties1.java 文件,用来映射我们在 application.yml 中的内容,这样一来我们就可以通过操作对象的方式来获得配置文件的内容了

package com.heardfate.springboot.demo.properties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * @since: 2018/10/21 * @author: Mr.HeardFate */ @Component @ConfigurationProperties(prefix = "test") public class MyTestProperties1 { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "MyTestProperties1{" + "age=" + age + ", name='" + name + '\'' + '}'; } }

自定义属性配置

接下来我们通过 HelloController 用来注入 MyTestProperties1 测试我们编写的代码,值得注意的是 Spring4.x 以后,推荐使用构造函数的形式注入属性…

package com.heardfate.springboot.demo.controller; import com.heardfate.springboot.demo.properties.MyTestProperties1; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @since: 2018/10/18 * @author: Mr.HeardFate */ @RestController @EnableConfigurationProperties({MyTestProperties1.class}) public class HelloController { @Autowired private MyTestProperties1 myTestProperties1; @RequestMapping("/") public String index() { return "Greetings from Spring Boot!"; } @RequestMapping("/pro1") public MyTestProperties1 myProperties1() { System.out.println("=====================MyTestProperties1====================="); System.out.println(myTestProperties1.toString()); System.out.println("=====================MyTestProperties1====================="); return myTestProperties1; } }

启动项目,打开浏览器,输入如下地址: http://localhost:8080/pro1,观察控制台,监听到如下内容则表示程序正确

=====================MyTestProperties1===================== MyTestProperties1{age=22, name='testUser'} =====================MyTestProperties1=====================

自定义属性配置

自定义文件配置

YML的缺点:不能通过@PropertySource注解加载! 如果需要使用@PropertySource注解的方式加载值,那就要使用properties文件!
YML的缺点:不能通过@PropertySource注解加载! 如果需要使用@PropertySource注解的方式加载值,那就要使用properties文件!
YML的缺点:不能通过@PropertySource注解加载! 如果需要使用@PropertySource注解的方式加载值,那就要使用properties文件!

定义一个名为 testProperties.properties 的资源文件,自定义配置文件的命名不强制 application 开头

com.heardfate.name=heardfate com.heardfate.age=18 com.heardfate.email=admin@heardfate.com

自定义文件配置

其次定义 src/main/java/com/heardfate/springboot/demo/properties/MyTestProperties2.java 文件,用来映射我们在 testProperties.properties 中的内容。

package com.heardfate.springboot.demo.properties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * @since: 2018/10/21 * @author: Mr.HeardFate */ @Component @PropertySource("classpath:testProperties.properties") @ConfigurationProperties(prefix = "com.heardfate") public class MyTestProperties2 { private int age; private String name; private String email; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "MyTestProperties2{" + "age=" + age + ", name='" + name + '\'' + ", email='" + email + '\'' + '}'; } } ![自定义文件配置](https://img.heardfate.com:442/springboot/demo/01/17.jpeg)

接下来在 HelloController 用来注入 MyTestProperties2 测试我们编写的代码

@Autowired private MyTestProperties2 myTestProperties2; @RequestMapping("/pro2") public MyTestProperties2 myProperties2() { System.out.println("=====================MyTestProperties2====================="); System.out.println(myTestProperties2.toString()); System.out.println("=====================MyTestProperties2====================="); return myTestProperties2; }

打开浏览器,输入如下地址: http://localhost:8080/pro2,观察控制台,监听到如下内容则表示程序正确

=====================MyTestProperties2===================== MyTestProperties2{age=18, name='heardfate', email='admin@heardfate.com'} =====================MyTestProperties2=====================

自定义文件配置

随机值配置

配置文件中 ${random} 可以用来生成各种不同类型的随机值,从而简化了代码生成的麻烦,例如 生成 int 值、long 值或者 string 字符串。

#随机值 com: heardfate: random: # 随机字符串 secret: ${random.value} # 随机int number: ${random.int} # 随机long bignumber: ${random.long} # UUID值 uuid: ${random.uuid} # 10以内的随机数 lessThan: ${random.int(10)} # 10-100的随机数 inRange: ${random.int[10,100]} # 100-1000的随机数,100前面和1000后面可以是 -,(,[ 等任意字符 int.inRange: ${random.int-100,1000-} inRange2: ${random.int(100,1000)}

随机值配置

其次定义 src/main/java/com/heardfate/springboot/demo/properties/MyTestRandomProperties.java 文件,用来映射我们在 application.ymlcom.heardfate.random 的内容。

package com.heardfate.springboot.demo.properties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * @since: 2018/10/21 * @author: Mr.HeardFate */ @Component @ConfigurationProperties(prefix = "com.heardfate.random") public class MyTestRandomProperties { // # 随机字符串 private String secret; // # 随机int private int number; // # 随机long private long bignumber; // # UUID值 private String uuid; // # 10以内的随机数 private int lessThan; // # 10-100的随机数 private int inRange; // # 100前面和1000后面可以是 -,(,[ 等任意字符 int.inRange: ${random.int-100,1000-} private int inRange2; public String getSecret() { return secret; } public void setSecret(String secret) { this.secret = secret; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public long getBignumber() { return bignumber; } public void setBignumber(long bignumber) { this.bignumber = bignumber; } public String getUuid() { return uuid; } public void setUuid(String uuid) { this.uuid = uuid; } public int getLessThan() { return lessThan; } public void setLessThan(int lessThan) { this.lessThan = lessThan; } public int getInRange() { return inRange; } public void setInRange(int inRange) { this.inRange = inRange; } public int getInRange2() { return inRange2; } public void setInRange2(int inRange2) { this.inRange2 = inRange2; } @Override public String toString() { return "MyTestRandomProperties{" + "secret='" + secret + '\'' + ", number=" + number + ", bignumber=" + bignumber + ", uuid='" + uuid + '\'' + ", lessThan=" + lessThan + ", inRange=" + inRange + ", inRange2=" + inRange2 + '}'; } }

随机值配置
接下来在 HelloController 用来注入 myTestRandomProperties 测试我们编写的代码

@Autowired private MyTestRandomProperties myTestRandomProperties; @RequestMapping("/random") public MyTestRandomProperties myTestRandomProperties() { System.out.println("=====================MyTestRandomProperties====================="); System.out.println(myTestRandomProperties.toString()); System.out.println("=====================MyTestRandomProperties====================="); return myTestRandomProperties; }

打开浏览器,输入如下地址: http://localhost:8080/random,观察控制台,监听到如下内容则表示程序正确

=====================MyTestRandomProperties===================== MyTestRandomProperties{secret='3a1720de4c4b2ca95762fa48ccbbdd78', number=19380060, bignumber=-3053795025857769306, uuid='4e440c8c-0e9c-42c6-a445-dc2497d946bb', lessThan=7, inRange=40, inRange2=884} =====================MyTestRandomProperties=====================

随机值配置

多环境化配置

在真实的应用中,常常会有多个环境(如:开发,测试,生产等),不同的环境数据库连接都不一样,这个时候就需要用到 spring.profile.active 的强大功能了,它的格式为 application-{profile}.properties,这里的 application 为前缀不能改,{profile} 是我们自己定义的。

创建 application-dev.ymlapplication-test.ymlapplication-prod.yml,内容分别如下

application-dev.yml

server: port: 8082

application-test.yml

server: port: 8083

application-prod.yml

server: port: 8084

多环境化配置

application.yml 配置文件中写入

spring: profiles: active: dev

这个时候我们再次访问 http://localhost:8080/pro1 就没用了,因为我们设置了它的 server: port: 8082,所以新的端口是 8082,新的访问路径:http://localhost:8082/pro1由此可以看出我们激活不同的配置读取的端口或属性值是不一样的
多环境化配置

外部命令引导

前面三种方式都是基于配置文件层面的,那么有没有办法外部引导呢,假设这样的场景,我们对已经开发完成的代码打包发布,期间在测试环境测试通过了,那么即可发布上生产,这个时候是修改 application.properties 的配置方便还是直接在命令参数配置方便呢,毫无疑问是后者更有说服力。默认情况下,SpringApplication 会将命令行选项参数(即:–property,如–server.port=9000)添加到 Environment,命令行属性始终优先于其他属性源。

如何测试?

  • 通过 IDEA 打包项目,双击 package 即可
    外部命令引导

  • 打包完毕后进入到:~/IdeaProjects/springboot-demo/demo01/target 目录中去,我们可以发现一个名为 demo01-0.0.1-SNAPSHOT.jar 的包

  • 接着在打开 命令行 程序,输入:java -jar demo01-0.0.1-SNAPSHOT.jar --spring.profiles.active=test --test.age=12。仔细观察**spring.profiles.active=testtest.age=12** 这俩配置的键值是不是似曾相识(不认识的请从开头认真阅读)
    外部命令引导

  • 最后输入测试地址:http://localhost:8083/pro1 我们可以发现打印的变成了 MyTestProperties1{age=12, name='testUser'}
    外部命令引导

配置文件的优先级

application.properties 和 application.yml 文件可以放在一下四个位置:

  • 外置,在相对于应用程序运行目录的/congfig 子目录里。
  • 外置,在应用程序运行的目录里
  • 内置,在 config 包内
  • 内置,在 Classpath 根目录

同样,这个列表按照优先级排序,也就是说,src/main/resources/config 下 application.properties 覆盖 src/main/resources 下 application.properties 中相同的属性,如图:
配置文件的优先级

此外,如果你在相同优先级位置同时有 application.properties 和 application.yml,那么 application.yml 里面的属性就会覆盖 application.properties 里的属性。

  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    948 引用 • 1460 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...