SpringBoot系列(八):Spring Boot微服务项目配置文件详解


作者: 修罗debug
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

摘要:本文我们将详细分享介绍如何基于Spring Boot搭建的项目使用其配置文件,其中内容将包括如何读取配置文件中变量的值,如何将配置文件中变量的值映射为Java Bean,如何加载使用自定义的配置文件以及如何进行多环境的切换!

内容:在有些情况下,我们不希望直接在代码里写死“属于配置”的东西,比如常见的数据库连接信息、第三方平台授权账号密钥信息等等,而更多的是希望将这些信息放在某个地方,可供我们动态、灵活地进行修改,一般情况下,这个地方指的便是“配置文件”!

下面我们将基于前文Spring Boot搭建的项目使用配置文件,其中,将主要从以下几个方面进行展开讲解:

(1)如何读取配置文件中变量的值

(2)如何将配置文件中变量的值映射为Java Bean

(3)如何加载使用自定义的配置文件

(4)如何进行多环境的切换

废话不多讲,咱们直接进入代码实战环节。

一、“如何读取配置文件中变量的值”:可以通过@Value(“${}”)或者Environment对象实例提供的api进行获取。

(1)首先是在application.properties配置文件中 加入以下的配置信息:

order.title=订单标题
order.info=订单详情
order.price=45.5
order.id=10

(2)然后是建议一个PropertyController,编写一个请求方法,其源代码如下所示:  

@RestController
@RequestMapping("order")
public class PropertyController {
//从配置文件中读取变量的值的第一种方式
@Value("${order.title}")
private String orderTitle;

@Value("${order.id}")
private Integer orderId;

@GetMapping("info/1")
public BaseResponse info1(){
BaseResponse response=new BaseResponse(StatusCode.Success);
Map<String,Object> resMap= Maps.newHashMap();
try {
resMap.put("orderTitle",orderTitle);
resMap.put("orderId",orderId);

response.setData(resMap);
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}

//从配置文件中读取变量的值的第二种方式
@Autowired
private Environment env;

@GetMapping("info/2")
public BaseResponse info2(){
BaseResponse response=new BaseResponse(StatusCode.Success);
Map<String,Object> resMap= Maps.newHashMap();
try {
resMap.put("orderInfo",env.getProperty("order.info"));
resMap.put("orderPrice",env.getProperty("order.price",Double.class));

response.setData(resMap);
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}
}

(3)将项目跑起来,然后分别发起请求:http://localhost:8081/technology/order/info/1

http://localhost:8081/technology/order/info/2 可以分别得到如下两张图的响应结果,如下两张图所示:





二、“如何将配置文件中变量的值映射为Java Bean”:可以通过@ConfigurationProperties + @Component 注解的方式实现这种效果

(1)我们仍然以上面配置文件application.properties中配置的变量值为例:

order.title=订单标题
order.info=订单详情
order.price=45.5
order.id=10

如果此时,order.xxx还有10几个,而我们仍然采用@Value或者Environment进行读取的话,那将会是件“蛋疼”的事情(要知道,程序员是最会、最想偷懒的!)故而,我们会想办法,能不能将这些属于order 实体的信息归结到一个“类”中去呢?

答案是显然可以!

我们可以采用 @ConfigurationProperties + @Component 注解的方式 实现 配置文件中变量自动映射为Java Bean,如下代码所示:

@ConfigurationProperties(prefix = "order")
@Component
@ToString
@Data
public class OrderDto implements Serializable{
private String title;
private String info;
private Double price;
private Integer id;
}

最后,我们是在PropertyController中开发一个请求方法,其完整源代码如下所示:  

    @Autowired
private OrderDto orderDto;

@GetMapping("info/3")
public BaseResponse info3(){
BaseResponse response=new BaseResponse(StatusCode.Success);
Map<String,Object> resMap= Maps.newHashMap();
try {
resMap.put("orderDto",orderDto);
resMap.put("orderDto的id",orderDto.getId());

response.setData(resMap);
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}

(2)将项目跑起来,然后发起请求:http://localhost:8081/technology/order/info/3 可以得到如下图的响应结果,如下图所示:  



三、“如何加载使用自定义的配置文件”:可以通过@ConfigurationProperties + @PropertySource(value = "classpath:配置文件所在位置") + @Component 组合注解的方式进行实现。

(1)首先,先在application.properties同目录下新建一个新的配置文件handsome.properties,在该配置文件中加入如下的变量配置信息:

www.baidu.com.title=百度
www.baidu.com.age=20

  然后,创建一个实体类HandsomeDto,其完整源代码如下所示:  

@Data
@ToString

@ConfigurationProperties(prefix = "www.baidu.com")
@PropertySource(value = "classpath:handsome.properties")
@Component
public class HandsomeDto implements Serializable{
private String title;
private Integer age;
}


即主要是加入@PropertySource(value = "classpath:handsome.properties") 的配置信息,将指定的配置文件加载进来!  同样的道理,我们在PropertyController中开发一个新的请求方法,如下所示:

    @Autowired
private HandsomeDto handsomeDto;

@GetMapping("info/4")
public BaseResponse info4(){
BaseResponse response=new BaseResponse(StatusCode.Success);
Map<String,Object> resMap= Maps.newHashMap();
try {
resMap.put("handsomeDto",handsomeDto);
resMap.put("handsomeDto的title",handsomeDto.getTitle());

response.setData(resMap);
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}

(2)将项目跑起来,然后发起请求:http://localhost:8081/technology/order/info/4 可以得到如下图的响应结果,如下图所示:  



四、“如何进行多环境的切换”:可以直接在配置文件application.properties中动态切换这个变量的值,如果 spring.profiles.active=prod,表示应用将切换到生产环境(读取的配置文件将为 application-prod.properties ;如果 spring.profiles.active=test,表示应用将切换到测试环境(读取的配置文件将为 application- test.properties)

(1)只需要在配置文件application.properties中动态调整变量 pring.profiles.active 的取值即可,如果为prod,则代表“生产环境”(application-prod.properties),如果为“test”,则代表“测试环境”(application-test.properties),如果为“dev”,则代表“开发环境”(application-dev.properties)

为了更好的进行测试,我们在application-prod.properties配置文件中添加如下的配置信息:

order.title=订单标题-生产环境
order.info=订单详情-生产环境
order.price=46
order.id=11


用于覆盖配置文件application.properties 中相对应的配置信息,并设置 spring.profiles.active=prod ,即代表此时启动的应用环境为 生产环境 prod!其读取的信息,将会以生产环境的配置覆盖掉默认的环境配置!

此时再次发起请求:http://localhost:8081/technology/order/info/3  可以得到跟前面请求时不一样的响应结果,如下图所示:



补充:

1、本文涉及到的相关的源代码可以到此地址,check出来进行查看学习:

https://gitee.com/steadyjack/SpringBootTechnology

2、目前Debug已将本文所涉及的内容整理录制成视频教程,感兴趣的小伙伴可以前往观看学习:

https://www.fightjava.com/web/index/course/detail/5

3、关注一下Debug的技术微信公众号,最新的技术文章、技术课程以及技术专栏将会第一时间在公众号发布哦!