springboot多环境配置文件,如何包含多个yml配置文件?看这一篇就够了

在开发springboot项目时,通常一套程序会被应用和安装到几个不同的环境,比如:开发,测试,生产等。其中每个环境的数据库地址,服务器端口等等配置都会不同。如果为不同的环境打包的时候都要频繁修改配置文件的话,那必将是个非常繁琐且容易发生错误的事情。

对于多环境配置,通过配置多份不同环境的配置文件,在通过打包启动命令进行区分会更灵活,方便。
解决
1.在spring中多环境配置文件名需要满足application-{profile}.properties的格式

其中{profile}对应的是环境标识,比如:

application-dev.properties:开发环境
application-test.properties:测试环境
application-prod.properties:生产环境

在这里插入图片描述

至于哪个具体环境的配置文件被加载,需要在application.properties文件中通过spring.profiles.active属性来设置,其值对应${profile}值。

如:spring.profiles.active = test 就会加载application-test.properties配置文件内容。

2.如果不想在项目中写死环境配置,也可以在打包或者运行的时候传入环境参数来确定。

**如:java -jar  ${jar_name} --spring.profiles.active=test**

再比如多环境:

启动命令为

//开发环境

java -jar app.jar --spring.profiles.active=dev--server.port=8060

//测试环境

java -jar app.jar --spring.profiles.active=qa --server.port=8060

//生产环境

java -jar app.jar --spring.profiles.active=prod --server.port=8060

可以再结合日志配置:

spring:
  profiles:
    #指定读取配置文件:dev(开发环境),prod(生产环境),qa(测试环境)
    active: qa

#日志
logging:
  config: classpath:logback-${spring.profiles.active}.xml

3.如果同一个环境有多个配置文件,可以通过spirng.profiles.include实现多配置文件
在这里插入图片描述

4.如果想在某个配置文件中引用其他配置文件的内容,可以使用${}符号实现
在这里插入图片描述
在这里插入图片描述
5.多环境下的优先级别是怎样的?


#application.properties 优先级从高到低,application.yml文件优先级也一样  
#级别高的会覆盖级别低的,级别高没有的,级别低有的配置项会同样生效  
   
#1-- 项目根目录config文件夹里面(优先级最高)  
#./config/  
   
#2--项目根目录  
#./    
   
#3-- src/main/resources/config/文件夹里面  
#classpath:/config    
   
#4-- src/main/resources/  
#classpath:/     
   
#1-4优先级从高到低,优先级高的配置内容会覆盖优先级低的配置内容  
server.port=8081 

在这里插入图片描述
在运行时,使用cmd命令行指定特定的配置文件(优化级最高),cmd命令如下:
这种情况可以加载打包后需要修改配置文件的运行,可以使用项目外的配置,如D盘的配置

java -jar lqyspringboot-0.0.1-SNAPSHOT.jar --spring.config.location=D:/application.properties

注意:

级别高的配置会覆盖级别低的相同配置,级别高的配置没有的项,级别低有的项会同样生效。
也就是说,无论级别高低,配置都会生效,只是相同的配置被级别高的配置覆盖。  

6.如何获取application.yml中的变量?
上面已经使用了变量,这里再统计一下
第一种方式获取

1.application.yml文件

server:
  port: 8088  #项目端口号
  servlet:
    context-path: /SpringBoot  #访问项目名称
  
zidingyiUrl:
  http://127.0.0.0:8088

2.一个TestController测试类

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@PropertySource("classpath:application.yml")
//读取application.yml文件
public class TestController {
 
    //获取项目端口号
    @Value("${server.port}") 
     private String servePrort; 
         
         
    @Value("${server.servlet.context-path}") 
    private String contextPath; 
         
    @Value("${zidingyiUrl}") 
       private String zidingyiUrl;
     
        //http://localhost:8088/SpringBoot/get
        @GetMapping("/get")
        public void get() {
        //获取项目端口号server.port=8088
        System.out.println("项目端口号为:"+servePrort);
        //获取获取项目名称
        System.out.println("获取项目名称为:"+contextPath);
        //获取自定义属性zidingyiUrl
        System.out.println("获取项目名称为:"+zidingyiUrl);
        }
}
  

3.启动项目访问http://localhost:8088/SpringBoot/get可以看到控制台输出

项目端口号为:8088
获取项目名称为:/SpringBoot
  

第二种方式获取

1.application.yml文件

server:
  port: 8088  #项目端口号
  servlet:
    context-path: /SpringBoot  #访问项目名称
  
zidingyiUrl:
  http://127.0.0.0:8088

2.一个GetPropertiesController测试类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class GetPropertiesController {
 
    @Autowired 
      private Environment environment;
     
    //http://localhost:8088/SpringBoot/getProperties
    @GetMapping("/getProperties")
    public void getProperties() {
    //获取项目端口号server.port=8088
    System.out.println("项目端口号为:"+environment.getProperty("server.port"));
    //获取获取项目名称
    System.out.println("获取项目名称为:"+environment.getProperty("server.servlet.context-path"));
    //获取自定义属性zidingyiUrl
    System.out.println("获取自定义属性路径为:"+environment.getProperty("zidingyiUrl"));
    }
     
}
  

3.启动项目访问http://localhost:8088/SpringBoot/ getProperties可以看到控制台输出

项目端口号为:8088
获取项目名称为:/SpringBoot
获取自定义属性路径为:http://127.0.0.0:8088

7.@ConfigurationProperties下application.yml中的使用
  
在 Spring Boot 项目中,为满足以上要求,我们将大量的参数配置在 application.properties 或 application.yml 文件中,通过 @ConfigurationProperties 注解,我们可以方便的获取这些参数值

使用 @ConfigurationProperties 配置模块
假设我们正在搭建一个发送邮件的模块。在本地测试,我们不想该模块真的发送邮件,所以我们需要一个参数来「开关」 disable 这个功能。另外,我们希望为这些邮件配置一个默认的主题,这样,当我们查看邮件收件箱,通过邮件主题可以快速判断出这是测试邮件

在 application.properties 文件中创建这些参数:

在这里插入图片描述
我们可以使用 @Value 注解或着使用 Spring Environment bean 访问这些属性,是这种注入配置方式有时显得很笨重。我们将使用更安全的方式(@ConfigurationProperties )来获取这些属性
在这里插入图片描述
@ConfigurationProperties 的基本用法非常简单:我们为每个要捕获的外部属性提供一个带有字段的类。请注意以下几点:

前缀定义了哪些外部属性将绑定到类的字段上
根据 Spring Boot 宽松的绑定规则,类的属性名称必须与外部属性的名称匹配
我们可以简单地用一个值初始化一个字段来定义一个默认值
类本身可以是包私有的
类的字段必须有公共 setter 方法

Spring 宽松绑定规则 (relaxed binding)
Spring使用一些宽松的绑定属性规则。因此,以下变体都将绑定到 hostName 属性上:
在这里插入图片描述
如果我们将 MailModuleProperties 类型的 bean 注入到另一个 bean 中,这个 bean 现在可以以类型安全的方式访问那些外部配置参数的值。

但是,我们仍然需要让 Spring 知道我们的 @ConfigurationProperties 类存在,以便将其加载到应用程序上下文中
激活 @ConfigurationProperties
对于 Spring Boot,创建一个 MailModuleProperties 类型的 bean,我们可以通过下面几种方式将其添加到应用上下文中

首先,我们可以通过添加 @Component 注解让 Component Scan 扫描到
在这里插入图片描述
很显然,只有当类所在的包被 Spring @ComponentScan 注解扫描到才会生效,默认情况下,该注解会扫描在主应用类下的所有包结构

我们也可以通过 Spring 的 Java Configuration 特性实现同样的效果:
在这里插入图片描述
只要 MailModuleConfiguration 类被 Spring Boot 应用扫描到,我们就可以在应用上下文中访问 MailModuleProperties bean

我们还可以使用 @EnableConfigurationProperties 注解让我们的类被 Spring Boot 所知道,在该注解中其实是用了@Import(EnableConfigurationPropertiesImportSelector.class) 实现,大家可以看一下
在这里插入图片描述
激活一个 @ConfigurationProperties 类的最佳方式是什么?
所有上述方法都同样有效。然而,我建议模块化你的应用程序,并让每个模块提供自己的@ConfigurationProperties 类,只提供它需要的属性,就像我们在上面的代码中对邮件模块所做的那样。这使得在不影响其他模块的情况下重构一个模块中的属性变得容易。

因此,我不建议在应用程序类本身上使用 @EnableConfigurationProperties,如许多其他教程中所示,是在特定于模块的 @Configuration 类上使用@EnableConfigurationProperties,该类也可以利用包私有的可见性对应用程序的其余部分隐藏属性。

猜你喜欢

转载自blog.csdn.net/xiaorui51/article/details/108452181