6.Spring Boot配置文件(yml、properties)

目录


Spring Boot专栏目录(点击进入…)



Spring Boot配置文件(yml、properties)

Spring Boot提供了两种常用的配置文件,分别是properties文件和yml文件。作用都是修改Spring Boot自动配置的默认值。相对于properties文件而言,yml文件更年轻,也有很多的坑。可谓成也萧何败也萧何,yml通过空格来确定层级关系,使配置文件结构更清晰,但也会因为微不足道的空格而破坏了层级关系

Spring Boot使用一个全局的配置文件,而且配置文件的名字是固定的(两种)
①application.properties(properties中的数据是无序的)
②application.yml(yaml中的数据是有序的)

Spring Boot配置文件的作用是用来修改Spring Boot自动配置的默认值;Spring Boot在底层自动配置好;像Tomcat启动默认配置端口是8080。如果要修改,就在这两个文件的一种中来修改

YAML(YAML Ain’t a Markup Language,不是一种标记语言)

YAML是“YAML Ain’t a Markup Language”(YAML,不是一种标记语言)的递归缩写,使用的是一个递归写法 。在开发的这种语言时,YAML的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)

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

yaml和json区别?

没有谁好谁坏,合适才是最好的

配置文件描述
yaml比json优雅,注释更标准,适合做配置文件
json作为一种机器交换格式比yml强,更适合做api调用的数据交换

yaml文件规则

(1)yml文件的好处,天然的树状结构,一目了然,实质上跟properties是差不多的
(2)以空格的缩进程度来控制层级关系。空格的个数并不重要,只要左边空格对齐则视为同一个层级,注意不能用tab代替空格(不支持tab缩进)
(3)大小写敏感
(4)可以使用“-小写字母”或“_小写字母”来代替“大写字母”,如userName与user-name,user_name含义是一样的

key:  value     格式书写
key 后面跟着冒号,再后面跟着一个空格,然后是值

以修改端口为例 :

yml:
server:
  port: 8081

xml:
<server>
	<port>8081</port>
</server>

xml配置将太多的浪费在了标签上面


yaml数据结构

语法:key:(空格)value

表示一对键值对(空格必须有),以(空格)的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的;属性和值也是大小写敏感。

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

字符串、布尔类型、数值、日期。字符串默认不加引号,单引号会转义特殊字符。日期格式支持yyyy/MM/dd HH:mm:ss

// 字面直接来写,字符串默认不用加上单引号或者双引号
k: v

“”:双引号;不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思

name:  "zhangsan \n lisi"
// 输出:zhangsan 换行  lisi

‘’:单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据

name:  ‘zhangsan \n lisi’
// 输出:zhangsan \n  lisi

(2)对象、Map(属性和值)(键值对)

由键值对组成,形如 key:(空格)value 的数据组成。冒号后面的空格是必须要有的,每组键值对占用一行,且缩进的程度要一致,也可以使用行内写法:{k1: v1, …kn: vn}

// 在下一行来写对象的属性和值的关系;注意缩进
k: v

对象还是k: v的方式

friends:
	lastName: zhangsan
	age: 20
	
行内写法:
friends: {lastName: zhangsan,age: 18}

(3)数组(List、Set)

由形如 -(空格)value 的数据组成。短横线后面的空格是必须要有的,每组数据占用一行,且缩进的程度要一致,也可以使用行内写法: [1,2,…n]

用 - 值表示数组中的一个元素

pets:
	- cat
	- dog
	- pig

行内写法:
pets: [cat,dog,pig]

(4)复合结构

上面三种数据结构任意组合


Properties(属性文件)

后缀properties是一种属性文件。 这种文件以key=value格式存储内容Java中可以使用Properties类来读取这个文件

String value = properties.getProperty(key)

其语法结构形如:key=value。注意中文乱码问题,需要转码


使用配置文件

1.配置文件

读取配置文件的时候默认读取的是application.properties、application.yml

①yml配置文件内容

user:
	id: 1
	sname: 张飞
	address: 东京
	email: www.zhangfei@qq.com

②properties配置文件内容

user.id=1
user.sname=\u5F20\u98DE
user.address=\u4E1C\u4EAC
user.email=www.zhangfei@qq.com

2.配置文件注入

properties、yml读取配置文件一致

(1)@ConfigurationProperties

JavaBean

@Component
@ConfigurationProperties(prefix = "user")
public class User {
	private int id;
	private String sname;
	private String address;
	private String email;
	// 省略getter/setter方法
}

@ConfigurationProperties(prefix =“person”)
将本类中的所有属性和配置文件中的相关配置进行绑定prefix ="person"表示对哪个文件进行绑定

@Component
表示这是一个容器,只有在容器中ConfigurationProperties才能使用

将配置文件中配置的每一个属性的值,映射到这个组件中@ConfigurationProperties:告诉Spring Boot将本类中的所有属性和配置文件中相关的配置进行绑定;

prefix = “person”:配置文件中哪个下面的所有属性进行一一映射,只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;
@ConfigurationProperties(prefix = “person”)默认从全局配置文件中获取值

ConfigurationProperties注解的优缺点
(1)可以从配置文件中批量注入属性;
(2)支持获取复杂的数据类型;
(3)对属性名匹配的要求较低,比如user-name,user_name,userName,USER_NAME都可以取值;
(4)支持JAVA的JSR303数据校验;
(5)缺点是不支持强大的SpEL表达式;


(2)@Value()

JavaBean

public class User {
    @value("12")                //字面量
	private int id;            
	 
    @value("${user.name}")     //从环境变量、配置文件中获取值
	private String sname;
	
    @value("${15*1}")           //El表达式
	private String address;
	
	private String email;
	
	// 省略getter/setter方法
}

@value(“${user.id}”)、${}相当于

<bean class="com.my.beans.User">
	<property name="name" value="" />
<bean/>

①字面量:""
②${key}:从环境变量
③#{SpEL}:配置文件中获取值

Value注解的优缺点
(1)只能一个个配置注入值;不支持数组、集合等复杂的数据类型;
(2)不支持数据校验;对属性名匹配有严格的要求。
(3)最大的特点:支持SpEL表达式,使其拥有更丰富的功能


@Value、@ConfigurationProperties获取值比较

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

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


配置文件占位符

yml与properties配置文件中,都可以使用占位符

随机数

随机数描述
${random.value}类似uuid的随机数,没有"-"连接
${random.uuid}生成一个uuid,有短杠连接
${random.int}随机取整型范围内的一个整型
${random.int(10)}随机生成一个10以内的整型
${random.int(100,200)}随机生成一个100-200 范围以内的整型
${random.long}随机取长整型范围内的一个长整型
${random.long(100,200)}随机生成长整型100-200范围内的一个长整型

占位符
语法${key:defaultValue}。若key不存在,则将defaultValue的值赋值给取值的对象

person.last-name=张三
person.dog.name=${person.last-name:小狗}
输出:张三
person.dog.name=${person.first-name:小狗}
输出:小狗

3.注入测试使用

@ConfigurationProperties,@Value()需要,@Environment不需要

@RunWith(SpringRunner.class)
@SpringBootTest
public class YMLTests {
	@AutoWired
	private User user;
	
	@Test
	public void fun() {//直接运行这个方法 ,而不是运行整个程序
		System.out.println(user);
	}
}

这个测试得在src/test/java下;项目加载文件的时候属性值才被注入进去,所以可运行项目来测试;也就是启动项目的时候applicaiton.properties/application.yml才被加载


配置文件读取

(1)@Environment

这种方法好像用的比较少,基本没用过
在类中直接注入Environment属性,利用它调用getProperty(“key”),就可以取到值value

@Autowired
private Environment env;

@Test
public void fun() {
	System.out.println(env.getProperty("user.name"));
}

(2)PropertiesLoaderUtils

配置文件监听器,来加载自定义配置文件

PropertiesListener.java 用来初始化加载配置文件

// 配置文件监听器,用来加载自定义配置文件
public class PropertiesListener implements ApplicationListener<ApplicationStartedEvent> {
	private String propertyFileName;
	
	public PropertiesListener(String propertyFileName) {
		this.propertyFileName = propertyFileName;
	}
	
	@Override
	public void onApplicationEvent(ApplicationStartedEvent event) {
		PropertiesListenerConfig.loadAllProperties(propertyFileName);
	}
}

PropertiesListenerConfig.java加载配置文件内容

public class PropertiesListenerConfig {
	public static Map<String, String> propertiesMap = new HashMap<>();
	private static void processProperties(Properties props) throws BeansException {
		propertiesMap = new HashMap<String, String>();
		for (Object key : props.keySet()) {
			String keyStr = key.toString();
			try {
				// PropertiesLoaderUtils的默认编码是ISO-8859-1,在这里转码一下
				propertiesMap.put(keyStr, new String(props.getProperty(keyStr).getBytes("ISO-8859-1"), "utf-8"));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (java.lang.Exception e) {
				e.printStackTrace();
			}
		}
	}
	public static void loadAllProperties(String propertyFileName) {
		try {
			Properties properties = PropertiesLoaderUtils.loadAllProperties(propertyFileName);
			processProperties(properties);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static String getProperty(String name) {
		return propertiesMap.get(name).toString();
	}
	public static Map<String, String> getAllProperty() {
		return propertiesMap;
	}
}

Applaction.java 启动类
通过注册监听器(Listeners) + PropertiesLoaderUtils的方式

@SpringBootApplication
public class Springbootone1Application {

	public static void main(String[] args) { 
		// 原本只有这一句:SpringApplication.run(Springbootone1Application.class, args);
		SpringApplication application = new SpringApplication(Springbootone1Application.class);
        // 第四种方式:注册监听器
        application.addListeners(new PropertiesListener("app-config.properties"));
        application.run(args);
	}
	
}

Controller

@RequestMapping("/listener")
public Map<String, Object> listener() {
	Map<String, Object> map = new HashMap<String, Object>();
	map.putAll(PropertiesListenerConfig.getAllProperty());
	return map;
}

加载配置文件

(1)@PropertySource(加载指定的配置文件)

注意:@PropertySource注解不支持加载yaml文件,支持properties文件

@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "user")
public class User {
	private int id;
	private String sname;
	private String address;
	private String email;
	
	// 省略getter/setter方法
}

(2)@ImportResource(导入Spring的配置文件)

让配置文件里面的内容生效;必须标注在类上

@ImportResource(value = {"classpath:applicationContext-dao.xml"})

Spring Boot里面没有Spring的配置文件,自己编写的配置文件,也不能自动识别;
所以想让Spring的配置文件生效,加载进来;就要将@ImportResource标注在一个配置类上
@ImportResource(locations = {“classpath:beans.xml”}):类路径上添加配置类的路径,导入Spring的配置文件让其生效

Spring的配置文件(beans.xml)

<?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="cn.qm.HelloService"></bean>
    
</beans>

@Bean(给容器中添加组件的方式)

推荐使用全注解的方式
1.配置类@Configuration代替Spring配置文件

2.使用@Bean给容器中添加组件

@Configuration
public class HelloService {
    //将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
    @Bean
    public HelloService helloService02(){
        System.out.println("配置类@Bean给容器中添加组件了...");
        return new HelloService();
    }
}

@Configuration
指明当前类是一个配置类;就是来替代之前的Spring配置文件,在配置文件中用标签添加组件
将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名


Profile

多Profile文件

在主配置文件编写的时候,文件名可以是application-{profile}.properties/yml
profile:可以随便命名,名之后在application.properties中配置就OK了。
Spring Boot默认使用配置文件为application.properties;

1.创建application-dev.properties文件

2.在application.properties配置文件中激活自定义的环境配置文件

server.port=8090		     #指定端口号
spring.profiles.active=dev	 #指定加载文件的profile,也就是-后的名字

配置完成后,也就会加载application-dev.properties/yml,及其默认配置文件
配置spring.profiles.active=dev就可以从application.properties加载到application-dev.properties/ yml文件


yml支持多文档块方式

server:
  port: 8081
spring:
  profiles:
    active: prod    #表示当前激活使用哪个环境,此时端口是8084;默认8081
    
---    #--- 表示环境的分割 ,分成不同的文档块
server:
  port: 8083
spring:
	profiles: dev
		
---
server:
  port: 8084
spring:
  profiles: prod  #指定属于哪个环境

配置文件加载位置

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

文件位置描述
–file:./config/文件路径config目录—>最高优先级
–file:./文件路径根目录—>其次
–classpath:/config/类路径config目录—>再其次
–classpath:/类路径根目录—>最低优先级

优先级由高到底,高优先级的配置会覆盖低优先级的配置
Spring Boot会从这四个位置全部加载主配置文件:互补配置;还可以通过spring.config.location来改变默认的配置文件位置。
项目打包好以后,可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置


外部配置加载顺序

Spring Boot也可以从以下位置加载配置;优先级从高到低;高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置

1.命令行参数;所有的配置都可以在命令行上进行指定

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar  --server.port=8087  --server.context-path=/abc

多个配置用空格分开; --配置项=值

2.来自java:comp/env的JNDI属性

3.Java系统属性(System.getProperties())

4.操作系统环境变量

5.RandomValuePropertySource配置的random.*属性值

6.jar包外部的application-{profile}.properties或application-{profile}.yml配置文件(带spring.profile)

7.jar包内部的application-{profile}.properties或application-{profile}.yml配置文件(带spring.profile)

8.jar包外部的application.properties或application.yml配置文件(不带spring.profile)

9.jar包内部的application.properties或application.yml配置文件(不带spring.profile)
由jar包外向jar包内进行寻找,优先加载带profile,再来加载不带profile

10.在应用@Configuration配置类中,用 @PropertySource 注解声明的属性文件

11.通过SpringApplication.setDefaultProperties指定的默认属性


配置文件的默认位置,及执行优先级顺序

首先,当创建一个Spring Boot工程时,默认resources目录下就有一个appliction.properties文件,可以在appliction.properties文件中进行项目配置,但是这个文件并非唯一的文件,在Spring Boot中,一共有4个地方可以存放application.properties文件。

1.当前项目根目录下的config目录下
2.当前项目的根目录下
3.resources目录下的config目录下
4.resources目录下

在这里插入图片描述


配置文件默认位置的修改

上面4个位置是默认位置,即Spring Boot启动,默认会从这四个位置按顺序去查找相关属性并加载。但是,这也不是绝对的,也可以在项目启动时自定义配置文件位置

例如:在resources目录下创建一个javaboy目录,目录中存放一个appliction.properties文件,那么正常情况下,当启动Spring Boot项目时,这个配置文件是不会被自动加载的。可以通过spring.config.location来手动的指定配置文件的位置,指定完成后,系统就会自动去该目录下查找application.properties文件


配置文件名问题

对于application.properties而言,不一定非要叫application,但是项目默认是去加载名为application的配置文件,如果文件不叫application也是可以的,但是,需要明确指定配置文件的文件名
方式和指定路径一致,这里的key是spring.config.name


Spring Boot配置文件(yml、properties)总结

(1)Spring Boot 支持两种格式的配置文件,其中YAML的数据结构比properties更清晰
(2)YAML 是专门用来写配置文件的语言,非常简洁和强大
(3)YAML 对空格的要求很严格,且不能用Tab键代替
(4)YAML 通过空格缩进的程度确定层级,冒号后面有空格,短横线后面有空格
(5)ConfigurationProperties注解适合批量注入配置文件中的属性,Value注解适合获取配置文件中的某一项
(6)ConfigurationProperties注解支持数据校验和获取复杂的数据,Value注解支持SpEL表达式

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未禾

您的支持是我最宝贵的财富!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值