SpringBoot2_配置

配置文件

1. 配置文件

SpringBoot使用一个全局的配置文件,配置文件名是固定的;

  • application.properties
  • application.yml

配置文件的作用:修改SpringBoot自动配置的默认值;SpringBoot在底层都给我们自动配置好;

YAML(YAML Ain’t Markup Language)

  • YAML A Markup Language:是一个标记语言
  • YAML isn’t Markup Language:不是一个标记语言;

标记语言:以前的配置文件;大多都使用的是 xxxx.xml文件;
YAML:以数据为中心,比json、xml等更适合做配置文件;

YAML:配置例子

server:
  port: 8081

properties:配置例子

server.prot=8081

xml:配置例子

<server>
	<port>8081</port>
</server>

我们选择yml配置文件方式,添加controller,访问localhost:8081/hello,程序能正常执行

2. YAML基本语法

2.1 基本语法

k: v:表示一对键值对(空格必须有);
空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的,如下例

server:
    port: 8081
    path: /hello

属性和值也是大小写敏感

2.2 值的写法

2.2.1 字面量:普通的值(数字,字符串,布尔)

字面值直接来写,字符串默认不加单引号或双引号

  • 双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
    name: "zhangsan \n lisi",输出为zhangsan 换行 lisi
  • 单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据
    name: 'zhangsan \n lisi',输出为zhangsan \n lisi
2.2.2 对象、Map(属性和值)(键值对)

对象还是k: v的方式,在下一行来写对象的属性和值的关系;注意缩进

friends:
	lastName: zhangsan
	age: 20

行内写法:

friends: {lastName: zhangsan,age: 18}
2.2.3 数组 (List、Set)

- value表示数组中的一个元素

pets:
 - cat
 - dog
 - pig

行内写法

pets: [cat,dog,pig]

3. 配置文件注入

步骤一:添加依赖

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

步骤二:添加实体类

添加一个Person类和一个Dog类
Person类

**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
 * prefix = "person":配置文件中哪个下面的所有属性进行一一映射
 * 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;所以需要添加@Component注解
 */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
	//getter、setter、toString()略
}

Dog类

public class Dog {
    private String name;
    private Integer age;
    //getter、setter、toString()略
}

步骤三:编写yaml配置文件

server:
  port: 8081

person:
  lastName: Jack
  age: 18
  boss: false
  birth: 2019/10/1
  maps: {k1: v1,k2: v2}
  list:
    - lisi
    - zhaoliu
  dog:
    name: Tom
    age: 2

步骤四:编写测试方法

@SpringBootTest
class SpringBootHelloworldQuickApplicationTests {

    @Autowired
    Person person;

    @Test
    void contextLoads() {
        System.out.println(person);
    }

}

步骤五:运行测试

在这里插入图片描述

4. 使用properties配置文件

把yml配置文件里的内容注释掉
在application.properties中添加如下代码

#server.port=8081

#配置person值
person.last-name=张三
person.age=18
person.birth=2019/10/1
person.boss=false
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=Tom
person.dog.age=2

properties配置文件默认使用UTF-8编码,需要对其进行转换,否则可能会出现中文乱码,需要在IDEA中做调整

  1. 修改IDEA配置
    在这里插入图片描述
  2. 在properties配置文件中添加编码方式
#server.port=8081

#配置编码方式
server.tomcat.uri-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.messages.encoding=UTF-8

#配置person值
person.last-name=张三
person.age=18
person.birth=2019/10/1
person.boss=false
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=Tom
person.dog.age=2

5. @Value与@ConfigurationProperties的区别

将实体类中的所有属性和配置文件中相关的配置进行绑定时,除了使用@ConfigurationProperties,还可以使用@Value
把Person类上方的@ConfigurationProperties注释掉,修改Person类的代码

@Component
//@ConfigurationProperties(prefix = "person")
public class Person {
    @Value("${person.last-name}")
    private String lastName;
    @Value("#{2*9}")
    private Integer age;
    @Value("#{true}")
    private Boolean boss;
    private Date birth;

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;

程序能够正常输出
在这里插入图片描述

  1. 如上所示,@Value支持SpEL,@ConfigurationProperties不支持

  2. 但是@Value不支持松散绑定,如果按照以下方式书写,程序会出错。

 @Value("${person.lastName}")
    private String lastName;

在application.properties配置文件中
以下两种方式都支持

person.last-name=张三
person.lastName=张三

故@ConfigurationProperties支持松散绑定

  1. @ConfigurationProperties支持JSR303数据校验,@Value不支持
    在lastName属性上方添加@Email,指定lastName必须是email的格式,使用@ConfigurationProperties,程序不会报错,而使用@Value,程序会报错

  2. @ConfigurationProperties支持复杂类型封装,@Value不支持
    在maps属性上方添加如下代码,程序会报错。@Value不支持Map这种复杂的类型

    @Value("${person.maps}")
    private Map<String, Object> maps;
  1. 如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value,如下例
@ResponseBody
@Controller
public class HelloController {

    @Value("${person.last-name}")
    private String name;

    @RequestMapping("/sayHello")
    public String sayHello(){
        return "hello " + name;
    }
}

请求/sayHello,就能获取到properties配置文件中的person.last-name
其中@ResponseBody@Controller可以由@RestController代替

总结如下

@ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定(松散语法)支持不支持
SpEL不支持支持
JSR303校验支持不支持
复杂类型封装支持不支持

配置文件yml还是properties他们都能获取到值;
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;

6. @PropertySource & @ImportResource & @Bean

6.1 @PropertySource

在以上几个小节中,我们把所有的配置信息都写在了一个配置文件applicaiton.properties中,但是如果想把有关person的配置信息提取出来,单独写到一个person.properties中,@PropertySource就可以排上用场
首先,新建一个person.properties文件

#配置person值
person.last-name=李四
person.age=18
person.birth=2019/10/1
person.boss=false
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=Tom
person.dog.age=2

在Person实体类上方添加注解@PropertySource(value = "classpath:person.properties"),如下所示

@PropertySource(value = "classpath:person.properties")
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
    ......

运行测试函数,能够读取到配置文件person.properties中的值
在这里插入图片描述

6.2 @ImportResource

我们首先在项目中添加一个简单的HelloService

package com.santiago.service;

public class HelloService {
}

再添加一个Spring配置文件beans.xml,把HelloService添加进来,如下所示

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="helloService" class="com.santiago.service.HelloService"></bean>
</beans>

添加一个测试类,测试ioc容器中是否包含helloService这个bean

@SpringBootTest
class SpringBootHelloworldQuickApplicationTests {
    @Autowired
    ApplicationContext ioc;

    @Test
    void testHelloService(){
        boolean b = ioc.containsBean("helloService");
        System.out.println(b);
    }
}

测试结果为false,这是因为Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别。
想让Spring的配置文件生效,加载进来;@ImportResource标注在一个配置类上,这里我们将其标注在主配置类上

@ImportResource(value = "classpath:beans.xml")
@SpringBootApplication
public class SpringBootHelloworldQuickApplication {

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

}

加载进来之后,再运行刚才的测试,结果为true

6.3 @Bean

6.2中spring配置文件,在SpringBoot中已经不使用了,取而代之的是配置类,推荐使用全注解的方式
首先将@ImportResource注释掉
接着写一个主配置类,当然也可以是主配置类。这里新建一个配置类MyAppConfig

/**
 * @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件
 *
 * 在配置文件中用<bean><bean/>标签添加组件
 *
 */
@Configuration
public class MyAppConfig {

    //将方法的返回值添加到容器中,容器中这个组件默认的id就是方法名,即id=helloService001
    @Bean
    public HelloService helloService001(){
        return new HelloService();
    }
}

@Bean的作用就是将方法的返回值添加到容器中,容器中这个组件默认的id就是方法名
除此之外,不要忘了在配置类上方添加注解**@Configuration**,指明当前类是一个配置类。
运行测试函数

    @Test
    void testHelloService(){
        boolean b = ioc.containsBean("helloService001");
        System.out.println(b);
    }

结果为true

7. 配置文件占位符

7.1 随机数

可以在配置文件的值中添加一些随机数,如下
${random.value}${random.int}${random.long}${random.int(10)}${random.int[1024,65536]}

7.2 使用占位符获取之前配置的值

如果没有可以是用:指定默认值,如下例
修改person.properties文件

person.last-name=张三${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
#之前配置的值中没有person.hello,可以指定默认值为hello,则输出结果为hello_dog
person.dog.age=15

运行测试函数

    @Test
    void contextLoads() {
        System.out.println(person);
    }

结果如下
在这里插入图片描述
在这里插入图片描述

8. Profile

Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境

8.1 多Profile文件形式

可以在资源文件夹下新建多个配置文件,指定不同的配置文件适用于不同的开发环境
格式:application-{profile}.propertiesapplication-{profile}.yml
在这里插入图片描述
分别在application.properties、application-dev.properties、application-prod.properties中指定端口号为8081、8082、8083
程序在运行的时候,默认使用的是application.properties,如果想指定其他profile,需要在application.properties添加激活代码spring.profiles.active=dev
在这里插入图片描述

8.2 多Profile文档块模式

yaml文件支持文档块模式,只使用一个yaml文件,使用---分割多个profile区(文档块),就可以实现多个profile,如下所示

server:
  port: 8081
spring:
  profiles:
    active: dev
---
server:
  port: 8082
spring:
  profiles: dev

---
server:
  port: 8083
spring:
  profiles: prod

程序运行时默认使用的是第一个文档块,可以在第一个文档块中指定要使用那个profile

8.3 Profile的激活方式

  • 配置文件方式:在配置文件中指定 spring.profiles.active=dev
    8.1 和 8.2 就是使用的配置文件方式
  • 命令行:在配置面板Program arguments中添加命令:--spring.profiles.active=dev
    在dos窗口使用java -jar命令运行jar包时,可以在其后添加命令--spring.profiles.active=dev指定运行环境
    在这里插入图片描述
  • jvm参数:–Dspring.profiles.active=dev,在配置面板VM Options:一栏中添加参数
    在这里插入图片描述

9. 配置文件加载位置

spring boot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件

  1. file:./config/
  2. file:./
  3. classpath:/config/
  4. classpath:/

以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。
如下所示,新建一个项目,用来测试配置文件加载位置,根据以上四个位置,创建同名application.properties
这四个文件分别对server.port=****赋了不同的值,程序启动时,端口号是根据这四个文件中的值决定的
如果文件1中已经进行了赋值,则后面三个文件中对端口号的配置皆不生效。以此类推,文件4优先级最低。
在这里插入图片描述
SpringBoot会从这四个位置全部加载主配置文件;互补配置;如下例
file:./config/的配置文件中配置端口号8084
file:./的配置文件中不仅配置端口号8081,而且配置项目访问路径

server.port=8081
#配置项目的访问路径
server.servlet.context-path=/boot02

添加controller,配置请求

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String sayHello(){
        return "hello";
    }
}

这四个配置文件形成互补配置,端口号采取file:./config/文件夹下的,项目访问路径采用file:./文件夹下的。
则访问hello请求是,请求路径必须为localhost:8084/boot02/hello
在这里插入图片描述

  • 我们还可以通过spring.config.location来改变默认的配置文件位置,但是这种方式适用于项目打包以后,使用命令行的方式进行配置
    例:我们在E盘放置一个application.properties文件,指定server.port=8085
    首先先讲项目打包
    在这里插入图片描述
    打包之后的jar包被放置在target目录,我们进入该jar包所在目录,使用命令行的方式运行jar包

注意:程序只将类路径下的文件进行打包,位于项目路路径的文件不打包。file:./config/file:./下的配置文件就不会打包进来。所以运行jar包的时候,jar包里的配置文件只有classpath:/config/application.propertiesclasspath:/application.properties在这里插入图片描述在这里插入图片描述
我们就可以看到端口号已经更改为8085
在这里插入图片描述

9. 外部配置文件加载顺序

Spring Boot 支持多种外部配置方式,下列配置方式的优先级从高到低,所有的配置符合互补配置

  1. 命令行参数
    将程序打包后,以java -jar的方式运行程序,可以在其后跟上命令行参数以修改配置信息
    在这里插入图片描述
    在这里插入图片描述
    修改多个配置信息需要在参数之间加空格就行了。但是命令行的方式只适用于修改少量配置信息的情况,批量修改配置信息,命令行的方式就不适用了。可以使用第6种方式,在jar包所在文件夹下创建一个application.properties配置文件
  2. 来自java:comp/env的JNDI属性
  3. Java系统属性(System.getProperties())
  4. 操作系统环境变量
  5. RandomValuePropertySource配置的random.*属性值
  6. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
    将项目打成jar包后,在jar包所在文件夹下创建一个配置文件application.properties,使用java -jar的方式运行此jar包,则会读取到该目录下配置文件的配置信息
  7. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  8. jar包外部的application.properties或application.yml(不带spring.profile)配置文件
  9. jar包内部的application.properties或application.yml(不带spring.profile)配置文件
  10. @Configuration注解类上的@PropertySource
  11. 通过SpringApplication.setDefaultProperties指定的默认属性
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值