❤️❤️❤️Spring专栏更新中,各位大佬觉得写得不错,支持一下,感谢了!❤️❤️❤️ Spring + Spring MVC + MyBatis专栏
前篇我们说完了SpringBoot的创建与使用,这篇讲SpringBoot的配置文件,那么SpringBoot的配置文件有什么用呢?那就到了这篇文章的主题——配置文件。
整个项目中所有重要的数据都是在配置文件中配置的,比如:
想象一下如果没有配置信息,那么 Spring Boot 项目就不能连接和操作数据库,甚至是不能保存可以用于排查问题的关键日志,所以配置文件的作用是非常重要的。
Spring Boot 配置文件主要分为以下两种格式:
为什么要学两种配置文件? 因为现在有的企业用.properties有的使用.yml
这就好像连锁店里面的统一服装一样,有两种不同的款式,properties 类型的配置文件就属于老款“服饰”,也是创建 Spring Boot 项目时默认的文件格式(主要是由于仓库里还有库存),而 yml 属于新版 款式,如果用户了解情况直接指定要新款服饰,那么就直接发给他。
特殊说明:🍓
properties 配置文件是最早期的配置文件格式,也是创建 Spring Boot 项目默认的配置文件。
properties 是以键值对的形式配置的,key 和 value 之间是以“=”连接的,如
# 配置项⽬端⼝号(使用 # 号来进行注释说明)
server.port=8084
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
使用上篇文章的SpringBoot项目 SpringBoot的创建和使用
我去修改项目端口号,修改为8888
#配置项目端口号
server.port=8888
启动项目:
可以看到控制台里显示端口号已被修改为:8888,我们浏览器打开:
浏览器也可以正常打开项目,修改端口号成功。
如果想要主动的读取项目中配置文件的内容,可以使用 @Value 注解来实现。
@Value 注解使用“${}”的格式读取,如下代码所示:
#配置项目端口号
server.port=8888
myName=孙悟空
修改了端口号 ,设置了myName属性,通过@Value 注解去读取,运行代码。
TestController
package com.example.springbootdemo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller//当前类为控制器
@ResponseBody//返回的是数据,而非页面
/*@RestController*/ //复合注解 = @Controller+@ResponseBody
public class TestController {
//读取配置文件 myName=张三
@Value("myName")
private String myName;
//请求映射 url 路由注册
@RequestMapping("hi")
public String sayHi(String s){
//为空为null 默认值处理
//if (s==null||s.equals("")){} 正常写法
if(!StringUtils.hasLength(s)){ //Spring中更简单的写法 判断是否有长度
s="张三";
}
return "你好"+myName;
}
}
???难道读取错误了吗?我的myName不是设置的孙悟空吗?why? 上面我们说了:@Value 注解使用“${}”的格式读取 所以直接使用双引号去读取这是错误的,这是一个错误示范
正确写法:
继续运行代码:
发现出现了乱码,这时可能有两种情况,1是读取的就是乱码,2是返回的乱码。我们可以去进行debug查看,找找原因。打好断点进行debug查看:
可以发现,原来我们读取的就是乱码,那么这个问题怎么去解决呢?
这在properties中也是一大痛点,因为在yml中就不会出现这类问题,我们需要额外在配置文件中去进行配置,这样才不会出现乱码问题。
添加下面配置,运行代码:
@PropertySource(value="classpath:/application.properties",encoding = "utf-8")
成功显示孙悟空。但是需要注意:
properties 配置是以 key-value 的形式配置的 ,但这样就无法避免配置文件中会有很多的冗余的信息。想要解决这个问题,可以使用 yml 配置文件的格式化。
yml 是 YAML 是缩写,它的全称 Yet Another Markup Language 翻译成中文就是“另一种标记⾔”。
yml 是树形结构的配置文件,它的基础语法是“key: value”,注意 key 和 value 之间使用英文冒汗加空格的方式组成的,其中的空格不可省略。
其中第一项的配置为正确的,key 也是高亮显示的,而第二项没有空格是错误的使用方式,第二项的 key 也没有高亮显示。
而在我的破解版上如果格式错误就会直接报错:
properties:
yml:
肉眼可以看出yml树状结果在很大程度上减少了配置的冗余。
yml的配置文件读取的和properties基本一样,都是使用@Value注解,格式都@Value("${}")。
现在来看看下面简单代码的运行
application.
yml
#正确配置方式
myText: java
#错误配置方式
#myText:java
TestController
package com.example.springbootdemo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller//当前类为控制器
@ResponseBody//返回的是数据,而非页面
/*@RestController*/ //复合注解 = @Controller+@ResponseBody
//导入外部资源的注解上 加入encoding配置
@PropertySource(value="classpath:/application.properties",encoding = "utf-8")
public class TestController {
//读取配置文件 myName=张三
// @Value("myName")错误示范
@Value("${myName}")
private String myName;
@Value("${myText}")
private String myText;
//请求映射 url 路由注册
@RequestMapping("hi")
public String sayHi(String s){
//为空为null 默认值处理
//if (s==null||s.equals("")){} 正常写法
if(!StringUtils.hasLength(s)){ //Spring中更简单的写法 判断是否有长度
s="张三";
}
return "你好"+myText+" + "+myName;
}
}
运行显示 :
前面我们已经解决了properties配置文件读取中文乱码问题,如果我们未去解决,那myName将是乱码显示,而yml无需配置则可以显示中文。我们将myText改成猪八戒,运行代码试试:
可以看到yml可以正常读取中文。
# 字符串
string.value: Hello
# 布尔值,true或false
boolean.value: true
boolean.value1: false
# 整数
int.value: 10
int.value1: 0b1010_0111_0100_1010_1110 # ⼆进制
# 浮点数
float.value: 3.14159
float.value1: 314159e-5 # 科学计数法
# Null,~代表null
null.value: ~
下面这样写不能出现关键字,不然会报空指针异常
# 字符串
string: #不能为关键字
value: hello
#布尔类型
booLean: #不能为关键字
value1: true
value2: false
# 整数
Int: #不能为关键字
value1: 10
value2: 0b1010_0111_0100_1010_1110 # 二进制
# 浮点数
fLoat: #不能为关键字
value1: 3.1415926
value2: 314159e-5 #科学计数法
# Null, ~ 表示 null
nUll: #不能为关键字
value: ~
读取方式还是一样的:
读取值为null的配置,可以发现什么都没有,为空
字符串默认不用加上单引号或者双引号,如果加英文的单双引号可以表示特殊的含义。
string:
value: hello
str1: Hello \n 你好.
str2: 'Hello \n 你好.'
str3: "Hello \n 你好."
运行下面代码:
package com.example.springbootdemo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.PostConstruct;
@Controller//当前类为控制器
@ResponseBody//返回的是数据,而非页面
/*@RestController*/ //复合注解 = @Controller+@ResponseBody
//导入外部资源的注解上 加入encoding配置
@PropertySource(value="classpath:/application.properties",encoding = "utf-8")
public class TestController {
//读取配置文件 myName=张三
// @Value("myName")错误示范
@Value("${string.str1}")
private String str1;
@Value("${string.str2}")
private String str2;
@Value("${string.str3}")
private String str3;
@PostConstruct//声明方法
public void postConstruct(){
System.out.println("string.str1:" + str1);
System.out.println("string.str2:" + str2);
System.out.println("string.str3:" + str3);
}
}
可以发现在双引号时str3 \n 进行了换行
由此可以得出结论:
我们还可以在 yml 中配置对象,如下配置:
student:
id: 1
name: Java
age: 18
或者是使用行内写法(与上面的写法作用一致):
student: {id: 1,name: Java,age: 18}
这个时候就不能用 @Value 来读取配置中的对象了(是一整个对象,而不是对象的属性),此时要使用另一个注解 @ConfigurationProperties 来读取,具体实现如下:
新建一个Student类
package com.example.springbootdemo;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "student")
@Data //lombok中的注解,提供getter和setter方法还要toString方法
public class Student {
private int id;
private String name;
private int age;
}
注意:以上代码中的 getter 和 setter 方法不能省略,要么使用@Data注解,要么生成getter 和 setter 方法。因为类中的值 赋值与取值 需要getter 和 setter 方法。
调用类TestController:
package com.example.springbootdemo;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
@Controller//当前类为控制器
@ResponseBody//返回的是数据,而非页面
/*@RestController*/ //复合注解 = @Controller+@ResponseBody
public class TestController {
//读取配置文件 myName=张三
// @Value("myName")错误示范
@Autowired
private Student student;
@PostConstruct//声明方法
public void postConstruct(){
System.out.println(student);
}
}
运行代码:
配置文件也可以配置 list 集合:或者是使用行内写法(与上面的写法作用一致)
types:
name:
- mysql
- sqlserver
- db2
或者是使用行内写法(与上面的写法作用一致)
types: {name: [mysql,sqlserver,db2]}
集合的读取和对象一样,也是使用@ConfigurationProperties 来读取的,具体实现如下:
@Component
@ConfigurationProperties("dbtypes")
@Data
public class ListConfig {
private List<String> name;
}
TestController 类
package com.example.springbootdemo;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
@Controller//当前类为控制器
@ResponseBody//返回的是数据,而非页面
/*@RestController*/ //复合注解 = @Controller+@ResponseBody
public class TestController {
//读取配置文件 myName=张三
// @Value("myName")错误示范
@Autowired
private ListConfig listConfig;
@PostConstruct//声明方法
public void postConstruct(){
System.out.println(listConfig.getName());
}
}
五、properties VS yml🍭
一定是 application-开头。
现在设置配置环境可以使用下面很方便的方法,下面active的值为dev,即为开发环境,如果是prod则为生成环境
spring:
profiles:
active: dev
application-dev.yml
server:
port: 9999
application-prod.yml
server:
port: 7777
设置不同的端口号,然后运行代码:
可以发现端口号变成了application-dev.yml中设置的端口号,
spring:
profiles:
active: prod
dev修改成prod,端口号就变成了 7777
这就很方便修改配置环境了