1、application.properties 简述

配置文件的使用和调整都非常方便,直接在项目默认的classpath下的application.properties文件中做调整即可。例如SpringBoot中默认的Tomcat毒启动端口是8080,我们需要调整为8081,那么直接在配置文件中调整server.port属性即可:

默认的application配置文件是 .properties 格式,实际上你还可以使用 YAML 格式,即 .yml,如上图中的配置用 YAML 格式写则是:

YAML 格式的配置文件,以缩进来表示属性之间的层级关系,从上面两种的对比我们已经能看出,YAML 格式的配置文件结构更加简洁清晰。当然,如果使用 YAML 格式的配置文件的话,还需要额外学习一下它的语法(阮一峰:YAML 语言教程),主要是结构表示,特别在书写时还应注意 缩进/空格 的使用,保证语法的正确性。

2、配置文件的加载顺序

(官方说明: 24.3 Application Property Files
SpringBoot应用会从如下四个位置加载application.properties文件,读取并载入到应用环境中去:
  • 当前目录下的 /config 目录
  • 当前目录
  • classpath下的 /config 目录
  • classpath 根目录

注意:如上的顺序是按照优先级排列的(从高到低),这意味着哪怕是同一个key的配置分别在不同位置的文件中,会优先选择 "当前目录下的 /config 目录"下的配置文件的值,也就是说,如果在优先级更高的位置找到了配置,则会无视优先级低的配置。这同样也意味着如果你想在测试/生产环境中快速修改配置参数,只需要在jar包之外的配置文件进行修改即可,不需要重新打包和部署应用。

这里的当前目录,是指与SpringBoot项目jar包同级的目录,如某个项目打包后的jar包在文件夹 /demo/springboot-demo.jar,则对应如上为:
  • /demo/config/application.properties
  • /demo/application.properties
  • /demo/springboot-demo.jar/BOOT-INF/classes/config/application.properties
  • /demo/springboot-demo.jar/BOOT-INF/classes/application.properties

当然,实际上展开来说SpringBoot读取配置的优先级不止上面的这几种,比如说优先级最高的实际上是命令行参数,即你在启动 jar 时通过命令行传入的配置参数。

3、自定义属性与加载

在类中,我们可以通过注解 @Value("${属性名}") 的方式将配置文件中的值注入到类中,如下配置文件有值:
server:
port: 8081 person:
name: zhangsan
age: 18
6
 
1
server:
2
  port: 8081
3

4
person:
5
  name: zhangsan
6
  age: 18

接着我们可以使用注解 @Value("${person.xxx}") 来将配置文件的值读入:
@Component
public class Person {
@Value("${person.name}")
private String name;
@Value("${person.age}")
private int age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
31
 
1
@Component
2
public class Person {
3
    @Value("${person.name}")
4
    private String name;
5
    @Value("${person.age}")
6
    private int age;
7

8
    public String getName() {
9
        return name;
10
    }
11

12
    public void setName(String name) {
13
        this.name = name;
14
    }
15

16
    public int getAge() {
17
        return age;
18
    }
19

20
    public void setAge(int age) {
21
        this.age = age;
22
    }
23

24
    @Override
25
    public String toString() {
26
        return "Person{" +
27
                "name='" + name + '\'' +
28
                ", age=" + age +
29
                '}';
30
    }
31
}

写个Controller看看吧:

4、@ConfigurationProperties

自定义属性与加载中提到的 @Value 方法,在配置较多时仍然显得有些繁重,SpringBoot提供了更简洁的方式,即 @ConfigurationProperties,该注解还有一个属性 prefix,可以指定配置文件的前缀,并且对类按属性名进行自动匹配。如上例中的 Person,换用 @ConfigurationProperties 的话,则如下:
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private int age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
30
 
1
@Component
2
@ConfigurationProperties(prefix = "person")
3
public class Person {
4
    private String name;
5
    private int age;
6

7
    public String getName() {
8
        return name;
9
    }
10

11
    public void setName(String name) {
12
        this.name = name;
13
    }
14

15
    public int getAge() {
16
        return age;
17
    }
18

19
    public void setAge(int age) {
20
        this.age = age;
21
    }
22

23
    @Override
24
    public String toString() {
25
        return "Person{" +
26
                "name='" + name + '\'' +
27
                ", age=" + age +
28
                '}';
29
    }
30
}

注意添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
5
 
1
<dependency>
2
    <groupId>org.springframework.boot</groupId>
3
    <artifactId>spring-boot-configuration-processor</artifactId>
4
    <optional>true</optional>
5
</dependency>

5、参数间的引用

在 application.properties 文件中,各个参数也可以相互引用,仍然是通过 ${属性名} 的方式,如下 zhangsan.name 就会引用 person.name 的值,age同理:
server:
port: 8081 person:
name: zhangsan
age: 18 zhangsan:
name: ${person.name}
age: ${person.age}
10
 
1
server:
2
  port: 8081
3

4
person:
5
  name: zhangsan
6
  age: 18
7
  
8
zhangsan:
9
  name: ${person.name}
10
  age: ${person.age}

6、使用随机值

在某些情况下,我们希望某些配置不是一个固定的值,那么可以在配置文件中使用 ${random.xx} 来产生int、long、String等随机值。如:
# 随机字符串
person.value=${random.value}
person.name=${random.string} # uuid
person.name=${random.uuid} # 随机int
person.age=${random.int} # 随机long
person.height=${random.long} # 10以内的随机数
preson.age=${random.int(100)} # 10-20的随机数
person.name=${random.int[10,20]}
18
 
1
# 随机字符串
2
person.value=${random.value}
3
person.name=${random.string}
4

5
# uuid
6
person.name=${random.uuid}
7

8
# 随机int
9
person.age=${random.int}
10

11
# 随机long
12
person.height=${random.long}
13

14
# 10以内的随机数
15
preson.age=${random.int(100)}
16

17
# 10-20的随机数
18
person.name=${random.int[10,20]}

7、Environment

这种方式是通过依赖注入Spring的Environment类实现的,并通过该类的getProperty方法配置的值:
@RestController
@RequestMapping("/demo/")
public class DemoController { @Autowired
private Environment environment; @RequestMapping("/printPerson.do")
public String printPerson() {
String personName = environment.getProperty("person.name");
return personName;
} }
14
 
1
@RestController
2
@RequestMapping("/demo/")
3
public class DemoController {
4

5
    @Autowired
6
    private Environment environment;
7

8
    @RequestMapping("/printPerson.do")
9
    public String printPerson() {
10
        String personName = environment.getProperty("person.name");
11
        return personName;
12
    }
13

14
}

另外在测试时发现一个小坑值得注意,当配置文件中的 person.name 值采用了 ${random.value},并绑定到 Person 类中,你会发现 environment 再每次获取 person.name 的值时是随机的,但是Person类中通过person.name赋予的值只是第一次的值,之后将不会主动改变:
@RestController
@RequestMapping("/demo/")
public class DemoController { @Autowired
private Person person; @Autowired
private Environment environment; @RequestMapping("/printPerson.do")
public String printPerson() {
String nameFromClass = person.getName();
String nameFromEnv = environment.getProperty("person.name");
System.out.println("class: " + nameFromClass);
System.out.println("env: " + nameFromEnv);
return nameFromEnv;
} }
20
 
1
@RestController
2
@RequestMapping("/demo/")
3
public class DemoController {
4

5
    @Autowired
6
    private Person person;
7

8
    @Autowired
9
    private Environment environment;
10

11
    @RequestMapping("/printPerson.do")
12
    public String printPerson() {
13
        String nameFromClass = person.getName();
14
        String nameFromEnv = environment.getProperty("person.name");
15
        System.out.println("class: " + nameFromClass);
16
        System.out.println("env: " + nameFromEnv);
17
        return nameFromEnv;
18
    }
19

20
}

分别访问三次,得到输出如下:
class: 80c628c7948c4270f831956945a0f26e
env: d8ff3f804268a929d365c663ade6894c
class: 80c628c7948c4270f831956945a0f26e
env: 9351315473098298f8416dae16bd1acb
class: 80c628c7948c4270f831956945a0f26e
env: ef78a4148b049c3fc25a71bddb560715
6
 
1
class: 80c628c7948c4270f831956945a0f26e
2
env: d8ff3f804268a929d365c663ade6894c
3
class: 80c628c7948c4270f831956945a0f26e
4
env: 9351315473098298f8416dae16bd1acb
5
class: 80c628c7948c4270f831956945a0f26e
6
env: ef78a4148b049c3fc25a71bddb560715


8、多环境配置 application-{profile}

我们在实际开发时,开发环境配置、测试环境配置、正式生产环境配置,配置信息都是不一样的(如开发环境的Tomcat端口是8080,生产环境的Tomcat端口则是8089),在频繁修改配置的过程中很容易出错。SpringBoot提供了更加简单的方式来解决这种问题,即通过配置多份不同环境下的配置文件。如原来仅有 application.yml,现在则新增三项,分别命名为:
  • application-dev.yml
  • application-test.yml
  • application-prod.yml

而在主配置文件 application.yml 中,则通过属性 spring.profiles.active 来指定使用哪份配置文件,如在开发时则指定 spring.profiles.active=dev,生产环境时 spring.profiles.active=prod

也可以在命令行启动时进行配置,这样哪怕重新部署也不需要修改application.yml:
java -jar xxx.jar --spring.profiles.active=prod
1
 
1
java -jar xxx.jar --spring.profiles.active=prod

9、加载多个自定义配置文件

我们当然喜欢多项配置能独立在不同的配置文件中进行管理,隔离而清晰,这就要求SpringBoot能够加载多个配置文件。如我们在 src/main/resource 下新建目录 config,新建配置文件 person.properties:

那么我们需要在Person类的注解上新增两个注解:@Configuration 和 @PropertySource,其中用 @PropertySource 注解中的 value 属性来指定需要读取的配置文件的路径,如下:
@Component
@Configuration
@PropertySource("classpath:config/person.properties")
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private int age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
32
 
1
@Component
2
@Configuration
3
@PropertySource("classpath:config/person.properties")
4
@ConfigurationProperties(prefix = "person")
5
public class Person {
6
    private String name;
7
    private int age;
8

9
    public String getName() {
10
        return name;
11
    }
12

13
    public void setName(String name) {
14
        this.name = name;
15
    }
16

17
    public int getAge() {
18
        return age;
19
    }
20

21
    public void setAge(int age) {
22
        this.age = age;
23
    }
24

25
    @Override
26
    public String toString() {
27
        return "Person{" +
28
                "name='" + name + '\'' +
29
                ", age=" + age +
30
                '}';
31
    }
32
}

这里不再使用 person.yml 作为配置文件,是因为 @PropertySource 注解不支持YAML文件格式,官方说明 “YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.”  看来在SpringBoot中,作为配置文件,还是使用 .properties 更为兼容。

10、打包jar时需要注意的自定义配置文件打包

在IDE上运行时正常,在打包项目为jar时再运行就提醒找不到配置文件,而这些配置文件往往是我们自定义的。我们到打包后的jar中目录下 BOOT-INF/classes 中发现,自定义的配置文件没有打包进来,这时需要注意,在pom.xml中添加 <resource>:
<build>
<!-- 打包资源文件 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
11
 
1
<build>
2
    <!-- 打包资源文件 -->
3
    <resources>
4
        <resource>
5
            <directory>src/main/resources</directory>
6
            <includes>
7
                <include>**/*</include>
8
            </includes>
9
        </resource>
10
    </resources>
11
</build>

其中 <include> 中的 **/* 表示通配符,所有目录下的所有文件,你也可以 **/*.properties 诸如此类。

11、@Configuration 和 @Bean

这个具体来说更应该是bean的注解配置方式:
  • @Configuration 标注在类上,相当于spring的xml配置文件中的 <beans>,作用为配置spring容器(应用上下文)

那么相应的
  • @Bean 标注在方法上(返回某个实例的方法),等价于spring的xml配置文件中的 <bean>,作用为注册bean对象


12、参考链接


[02] SpringBoot的项目属性配置的更多相关文章

  1. SpringBoot 入门:项目属性配置

    开发一个SpringBoot 项目,首当其冲,必然是配置项目 一.项目属性配置 1. SpringBoot自带了Tomcat服务器,通过使用项目配置文件来修改项目的配置,如图配置了部署在80端口,目录 ...

  2. Spring Boot项目属性配置

    接着上面的入门教程,我们来学习下Spring Boot的项目属性配置. 1.配置项目内置属性 属性配置主要是在application.properties文件里配置的(编写时有自动提示)这里我们将se ...

  3. VS项目属性配置实验过程

    (原创,转载注明出处:http://www.cnblogs.com/binxindoudou/p/4017975.html ) 一.实验背景 cocos2d-x已经发展的相对完善了,从项目的创建.编译 ...

  4. VS IDE 中Visual C++ 中的项目属性配置

    VS IDE 中Visual C++ 中的项目属性配置 一. Visual C++ 项目系统基于 MSBuild. 虽然可以直接在命令行上编辑 XML 项目文件和属性表,我们仍建议你使用 VS IDE ...

  5. springboot快速入门(二)——项目属性配置(日志详解)

    一.概述 application.properties就是springboot的属性配置文件 在使用spring boot过程中,可以发现项目中只需要极少的配置就能完成相应的功能,这归功于spring ...

  6. SpringBoot项目属性配置-第二章

    SpringBoot入门 1. 相信很多人选择Spring Boot主要是考虑到它既能兼顾Spring的强大功能,还能实现快速开发的便捷.我们在Spring Boot使用过程中,最直观的感受就是没有了 ...

  7. SpringBoot总结之属性配置

    一.SpringBoot简介 SpringBoot是spring团队提供的全新框架,主要目的是抛弃传统Spring应用繁琐的配置,该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配 ...

  8. 转载:VS项目属性配置总结

    本文来自:http://www.mamicode.com/info-detail-232474.html       https://www.cnblogs.com/alinh/p/8066820.h ...

  9. VS项目属性配置总结

    以下是针对VS2013下的VC++项目: Debug和Release说明: Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进 ...

随机推荐

  1. Python 函数的作用域

    python中的作用域有4种: 名称 介绍 L local,局部作用域,函数中定义的变量: E enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的: B ...

  2. php文件与HTML页面的数据交互

    注意:首先需要保证本地配置了php开发环境,如WAMP开发环境 WAMP配置:https://www.cnblogs.com/shiyiaccn/p/9984579.html php获取HTML页面返 ...

  3. 教你读懂vue源码技术教程

    由于 Vue 的源码采用 ES6,所以你至少应该掌握 ES6 才能看得懂,其次你最好对 package.json 中的字段的作用有所了解.由于 Vue 使用 Rollup 构建,所以你不了解 Roll ...

  4. GIS小知识

    1.GeoJson 2.EPSG:3857 几何对象:{"id":0,"style":null,"parts":[1],"poin ...

  5. SEO高手和SEO屌丝的八个区

    原文:http://www.it28.cn/sousuoyinqing/853085.html SEO这个行业并不规范,有些seo工程师可以拿着高薪,进行一些大型网站的seo工作,其实主要是UEO的工 ...

  6. centos7下安装rabbitmq

    RabbitMQ: RabbitMQ是流行的开源消息队列系统,是AMQP(Advanced Message Queuing Protocol高级消息队列协议)的标准实现,用erlang语言开发.Rab ...

  7. 针对模拟滚动条插件(jQuery.slimscroll.js)的修改

    在开发过程中程序员总会碰到产品经理提出的各种稀奇古怪的需求,尽管有些需求很奇葩,但不得不说有些须有还是能指引我们不断的学习与进步,最近在工作中就碰到这种问题.需求是要求在各主流浏览器上使用自定义的滚动 ...

  8. JVM内核优化

    1.垃圾回收器 JVM垃圾回收器有串行和并行两种. 1.1 Serial收集器(串行,单线程),现在使用较少 Serial一般收集新生代 SerialOld一般收集老年代(采用标记压缩算法) 1.2 ...

  9. 使用openssl在windows 10下本地xampp配置https开发环境

    安装win64OpenSSL-1_1_0j后重新启动:以管理员权限启动powershell; 执行以下命令 set OPENSSL_CONF=c:\xampp\apache\conf\openssl. ...

  10. python第二十九天-----继续学习第三模块——前几天旅行去了

    subprocess模块 import subprocess subprocess.getstatusoutput('dir')#接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结 ...