SpringBoot-配置文件

462 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

全局配置文件

Spring Boot 项目使用一个全局的配置文件 application.propertiesapplication.yml进行参数的配置。该文件保存在resources目录下或者 classpath 下的 /config目录下.

文件格式

如果是 application.properties 格式:

#修改 Tomcat 的端口为 8088
server.port=8088
#修改进入DispatcherServlet的规则为 *.html
server.servlet-path=*.html

如果是 application.yml 格式:

server:
  port: 8081
  servlet-path: *.html

更多默认可配置项:docs.spring.io/spring-boot…

属性配置占位符

支持引用配置中已出现的属性. 格式: ${xx.yy:zz} 表示使用 xx 对象的 yy 属性, zz 用来指定找不到 yy 属性时的默认值.

person.name=张三
person.qianming=${person.name}, 加油!
person.info=${person.name},${person.sex:男},${person.country:中国}

获取配置文件的内容

SpringBoot 提供了四种获取配置文件内容的方式 .

使用 PropertiesLoaderUtils

TODO

使用 @ConfigurationProperties 映射为实体类

对于 SpringBoot 项目,可以很方便的将配置文件中的参数值,映射到指定实体类上去获取使用。

1.导入配置文件处理器依赖, 这样配置文件进行绑定时就会有提示:

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

2.配置 application.yml

person:
  name: zhangsan
  age: 18
  birth: 2000/01/25
  maps: {k1: v1, k2: v2}
  lists:
    - lisi
    - zhaoliu
  dog:
    name: 旺财
    age: 2

3.对应的实体类 Person

@DNAA
// 注意: 只有当这个类是容器的组件时, 才可以使用该注解.
@Component
// 该注解告诉 SpringBoot 将本类中的所有属性和配置文件中以 person 开头的配置进行绑定.
@ConfigurationProperties(prefix="person")
public class PersonConfig {
    private String name;
    private Integer age;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
}

4.使用配置值

// 使用
@Autowired
private PersonConfig personConfig; //注入,和上面的 @ConfigurationProperties 注解所在的类的类名相同.

@GetMapping(value = "person")
public Person person(){
	return personConfig.getName();
}

5.注意

如果 在 key 中存在 大写字母, 且不是最后一级的, 则会报错. 如果是最后一级, 不会报错.

# 比如 下面 singleMonth 的写法就是错误的
settings:
  base:
    basePathWin: xxx
  singleMonth:
    basePath: xxx

#正确写法应该是 singleMonth -> single-month
settings:
  base:
    basePathWin: xxx
  single-month:
    basePath: xxx

同时配置类的 prefix 也需要改变 :

@Component
@ConfigurationProperties(prefix = "settings.single-month")
public class SingleMonthConfig {

    private String basePath;
}

使用 @Value 注解

比如如下配置:

person:
  name: zhangsan
  age: 18

如下方式获取:

@Value("${person.name}")
private String name;
// 注意,*.properties 文件中的中文默认以 ISO-8859-1 方式编码
// 因此需要对中文内容进行重新编码

@GetMapping(value = "person")
public String person(){
    System.out.println(name);
    return name;
}

使用 Environment 类

比如如下配置:

aliyun:
  sms:
    accessKeyId: xxxxxx
    accessKeySecret: yyyyy
    template_code: SMS_85735065
    sign_name: TS

如下方式获取:

import org.springframework.core.env.Environment;

@Autowired
private Environment env;	// 注入 Environment

public String sendSms(String mobile) {
    String accessKeyId = env.getProperty("aliyun.sms.accessKeyId");
    String accessKeySecret = env.getProperty("aliyun.sms.accessKeySecret");
    return "ok";
}

Environment源码 blog.csdn.net/cen50958/ar…

Environment源码 cloud.tencent.com/developer/a…

配置文件的加载顺序

SpringBoot 项目的配置文件分为内部的和外部的.

  • 外部的优先级高于内部的. ( 方便打包之后更改配置 )
  • 优先级由高到低高优先级的配置会覆盖低优先级的配置没有的配置进行互补配置.

项目内的配置文件加载顺序

SpringBoot 项目启动后,会自动扫描以下位置的 application.properties 或 application.yml 文件,作为默认配置文件 :

  • ./config/ ( 项目根路径下的 config 文件夹) 下图中的 8081
  • ./ (项目根路径) 下图中的 8082
  • classpath:/config/ (类路径下的 config 文件夹) 下图中的 8083
  • classpath:/ (类路径) 下图中的 8084

这几个文件在 IDEA 中的位置如图 :

上面四个位置的配置文件位置,优先级由高到低

注意:不是类路径下的配置文件在打包时,如果不做配置是不会打包进 jar 包中的,也会是说前两个配置在项目打包时,很容易忽略掉,所以尽量不要用前两个位置.

外部配置文件

外部配置有如下几种方式,并且几个位置的配置文件位置,优先级从高到低,高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置.

  • 命令行参数. 所有的配置项都可以在命令行上进行设置.
java -jar springboot-configuration.jar --server.port=8088 --server.servlet.context-path=/spring
  • 指定配置文件位置。启动项目时,可以用 spring.config.location指定配置文件的新位置.
java -jar springboot-configuration.jar --spring.config.location=F:/application.properties
  • 默认位置. 只要在 jar 包的同级目录, 放置一个 application.properties 或者 application.yml 配置文件,就会自动被使用.

\

读取指定名称的配置文件

上面演示的都是读取 application.yml 这种默认的配置文件,但是所有配置都放在一个文件中,可读性很差,一般都是分开到多个 *.yml 文件中,这又改如何获取呢?

@PropertySource 注解可以加载指定名称的配置件 *.properties 到 Spring 的 Environment 中。这样就可以配合 @Value 和 @ConfigurationProperties 使用。

  • @PropertySource + @Value 可以将自定义属性文件中的属性变量值注入到当前类的使用 @Value 注解的成员变量中.
  • @PropertySource + @ConfigurationProperties,可以将属性文件与一个 Java 类绑定,将属性文件中的变量值注入到该Java类的成员变量中.

@PropertySource 和 @Value 组合使用

代码在 Github 上的地址:

github.com/SanJingYe88…

在 resources 目录下存在一个名叫 config-1.properties 的配置文件,文件内容如下:

# 微信开放平台 appid
wx.open.app_id=wxe54c24e8ff2b2771
# 微信开放平台 appsecret
wx.open.app_secret=677a2d6bd69e88b5d7a2bbf42b6352b3
# 微信开放平台 重定向url
wx.open.redirect_url=https://qasso.huanxi.com/Login/callback

将其读取到项目中的 Config1 类上:

@Component
@PropertySource(value = {"classpath:wxConfig.properties"})
public class ConstantWxUtils implements InitializingBean {
    
    @Value("${wx.open.app_id}")
    private String appId;
    
    @Value("${wx.open.app_secret}")
    private String appSecret;
    
    @Value("${wx.open.redirect_url}")
    private String redirectUrl;
    
    public static String WX_OPEN_APP_ID;
    public static String WX_OPEN_APP_SECRET;
    public static String WX_OPEN_REDIRECT_URL;
    
    @Override
    public void afterPropertiesSet() throws Exception {
        WX_OPEN_APP_ID = appId;
        WX_OPEN_APP_SECRET = appSecret;
        WX_OPEN_REDIRECT_URL = redirectUrl;
    }
}

@PropertySource 和 @ConfigurationProperties 组合使用

代码在 Github 上的地址:

github.com/SanJingYe88…

注意,这里需要使用 spring-boot-configuration-processor 依赖.

在 resources 目录下存在一个名叫 config-2.properties 的配置文件,文件内容同上.

将其读取到项目中的 Config2 类上:

@Slf4j
@Getter
@Component
@PropertySource(value = {"classpath:config-2.properties"},encoding="utf-8")
@ConfigurationProperties(prefix = "wx.open1")
public class Config2 {
    private String appId;
    private String appSecret;
    private String redirectUrl;

    // 使用 set 方法证明配置确实加载了
    public void setAppId(String appId) {
        this.appId = appId;
        log.info("appId= {}", appId);
    }

    public void setAppSecret(String appSecret) {
        this.appSecret = appSecret;
        log.info("appSecret= {}", appSecret);
    }

    public void setRedirectUrl(String redirectUrl) {
        this.redirectUrl = redirectUrl;
        log.info("redirectUrl= {}", redirectUrl);
    }
}

这里遇到了如下几个问题:

  • 读取的配置乱码,即使已经对 IDEA 进行了设置,依旧乱码,使用 @PropertySource 注解的encoding属性指定编码方式.
  • 虽然 Conifg2 中指定读取 config-2.properties,但是如果 @ConfigurationProperties 注解中的 prefix 属性在其他 config 配置文件中存在的话,还是会错乱,所以这里的prefix 前缀需要唯一,不然有可能读取到其他配置文件件去.