Spring Boot的两种配置文件--properties VS yaml

2,329 阅读5分钟

10月份刚刚换了新工作,这也预示着全面转向Java技术栈,带着对Spring, Spring Boot, Mybatis, Maven等一切懵懂入职了新公司,领导第二天就发给我一个git仓库的链接,告诉我这个我们的项目模板,本着先让代码跑起来的原则,我去各种搜索springboot项目的基础,好在模板比较基础,能很快运行了起来,写个Controller, 连接到本地数据库也能跑通一个API,心想也挺简单嘛,看看如何跑起来的吧,于是开始研究代码,我瞬间就傻了,一会儿是yaml文件,一会儿是properties文件,一会又是xml配置文件,这都是干啥的,又是咋用的,能不能不写这么多配置文件,或者能不能统一用一种格式的配置文件。经过两天的研究和实验,终于大概了解各种文件的使用。 现将这些学习成果记录下来,以便后续查阅。 今天是一系列入门笔记的第一篇:Spring Boot的两种配置文件。

虽然Spring Boot中采用了大量的自动化配置,但是在实际的项目中经常需要一些自己的配置,这时候就需要使用配置文件了,在Spring Boot中提供了两种配置文件格式----properties文件和yaml文件.默认的配置文件名称是application.properties(或application.yaml)

这些配置文件放在哪

既然这些配置文件时Spring Boot默认的,那我是不是随便放到一个文件夹里就可以了, 你想多了, 当然是要按照规矩办事. Spring Boot在启动时会依此在下面的路径中寻找配置文件

  • 项目根目录下的config文件夹
  • 项目根目录
  • classpath下的config文件夹
  • classpath下

并且四个目录的优先级从上到下依次降低, 也就是说如果你在这四个目录下都定义了配置文件, 优先级高的会将优先级低的配置覆盖. 具体如下图所示:

下面我们使用数据库的配置来介绍如何使用两种不同格式的配置文件.

application.properties 的使用

spring.datasource.name=datasource
spring.datasource.druid.filters=stat
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springBucks?useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=yourusername
spring.datasource.password=yourpassword

application.yaml 的使用

spring:
  datasource:
    name: datasource
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: dreamfinal21
    druid:
      filters: stat
      initial-size: 5
      min-idle: 5
      max-active: 20
      max-wait: 60000
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000

可以换个配置文件名字吗

通常默认的配置文件已经足够我们使用了,但是有时我们会想换一个名字, 或者是给配置文件换一个位置(个人觉得没必要), 这些都是可以满足的. 如下的方式都可以呀;

在启动时指定配置文件的名字和位置

如果你将默认配置文件自定义成app.properties, 并且将其放在自定义的classpath:/customConfig/ 下, 当你把项目打成jar包后,启动时要指定配置文件的名称和位置.

  java -jar properties-0.0.1-SNAPSHOT.jar --spring.config.location=classpath:/customConfig/ --spring.config.name=app

当然在开发过程中你也可以借助IDE指定启动项配置,这里不详细阐述,个人不喜欢这种方式,有兴趣的可以自己上网搜索一下.

使用@PropertySource 注解

这里说明一下 application.properties文件是Spring Boot启动时默认会加载的配置, 一些自定义的配置是不建议写在这里面的,这时就需要写自定义的配置文件,但是自定义的配置文件默认时不会被Spring Boot加载的,这时就需要使用@PropertySource注解了. 另外需要注意的时@PeopertySource 注解是不支持yaml配置方式的.

下面给吃一个使用自定义的配置的实例, 这里我们自定义了一个配置文件user.properties, 内容如下:

  user.name=zhangsan
  user.age=23
  user.id=1
   @Component
   @PropertySource("classpath:user.properties")
   public class User{
      @Value("${user.id}")
      private Long id;
      @Value("${user.name}")
      private String name;
      @Value("${user.age}")
      private Long age;
      //getter/setter
   }

通过@PropertySource 引入自定义的配置文件的启发, 那我能否也通过该注解来加载系统配置文件呢? 于是我将application.properties文件重命名成app.properties, 并移动到classpath: /config1/下, 然后在SpringBoot启动类上加上如下注解:

  @SpringBootApplication
  @PropertySource("classpath:config1/app.properties")
  public class SpringBucksApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBucksApplication.class, args);
	}
  }

哈哈, 竟然也能启动

application-dev.properties或application-prod.properties 是干嘛用的

在实际项目中我们通常在不同的环境是需要不同的配置,比如在开发环境,测试环境已经线上环境的数据库配置可能都是不一样的,你看到的application-dev.properties或application-prod.properties就是帮你解决不同环境的配置问题的.Spring Boot约定不同的环境配置文件的名称规则是application-{profile}.properties. 其中{profile}是一个占位符,用于表示你定义的环境名称. 使用时你可以定义不同的环境配置文件,那我该怎么确定我使用的时哪个配置文件呢? 我就需要在Spring Boot的配置文件中指定激活哪一个profile, 如下所示(也可以使用yaml文件):

// 定义了active就使用active指定的profile, 否则使用default指定的profile,如果都不写, 那就没有profile可用啦.
spring.profile.active=dev 
spring.profile.defaut=dev

这里还要在提一点时@Profile注解,该注解用于指定只用在某个profile激活时才装配该Bean.比如有时我们希望在不同的环境下使用不同的datasource, 此时就需要@Profile注解发挥作用了.如下示例, 我们希望在开发环境使用内嵌的数据库, 但是在线上环境使用MySQL数据库,我们就可以像这样定义configuration.


    @Bean(name="dataSource")
    @Profile("dev")
    public DataSource embeddedDataSource() {
      return new EmbeddedDatabaseBuilder()
              .setType(EmbeddedDatabaseType.H2)
              .addScript("classpath:schema.sql")
              .addScript("classpath:test-data.sql")
              .build();
    }

    @Bean(name="dataSource")
    @Profile("prod")
    public DataSource hikariDataSource() {

        HikariConfig hikariConfig = new HikariConfig();

        hikariConfig.setDriverClassName("com.mysql.jdbc.Driver");
        hikariConfig.setJdbcUrl(hikaricpUrl);
        hikariConfig.setUsername(hikaricpUsername);
        hikariConfig.setPassword(hikaricpPassword);
        hikariConfig.setAutoCommit(true);
        hikariConfig.setTransactionIsolation("TRANSACTION_READ_COMMITTED");
        hikariConfig.setConnectionTimeout(5000);
        hikariConfig.setIdleTimeout(600000);
        hikariConfig.setMaxLifetime(1800000);
        hikariConfig.setMaximumPoolSize(5);
        hikariConfig.addDataSourceProperty("cachePrepStmts", "true");
        hikariConfig.addDataSourceProperty("prepStmtCacheSize", "250");
        hikariConfig.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        hikariConfig.addDataSourceProperty("allowMultiQueries", "true");

        HikariDataSource dataSource = new HikariDataSource(hikariConfig);

        return dataSource;
    }