这篇文章就进入了 Spring Boot 重要的一个环节就是关于 Spring Boot 的配置,因为在整个项目中重要的数据都是在配置文件中来配置的。
1、数据库的连接信息
之前在 JDBC 的时候数据库里面的连接信息都是写死在代码里面的,移植性差,如果项目复杂了,修改里面 JDBC 的代码还容易出错,但是在配置文件里面直接就是关键字和需要的信息(用户名,密码)。之后运维做修改或者测试的时候也容易检查修改连接信息。
2、项目的启动端口
当端口被占用的时候,你只需要在配置文件做出修改,特别是 8080 这个端口可能会老是被占用,以前解决的办法是找到占用 8080 这个端口的应用给他关闭掉才行成本大还麻烦。
3、第三方系统调用秘钥等的信息
公司A的一个项目中可能会借助第三方系统或者软件来搭配使用才能给用户完整的体验,就比如说出勤,在线上上课,公司A自己做了一个网站系统是来检查学生上课的出勤率,但是学生上课使用的视频软件是公司B做的,比如说腾讯课堂,小鹅通…这些视频软件,公司A自己是知道自己的学生用户的,但是公司B是不知道的,为了保护用户数据的安全公司B是不会轻易交出用户的信息,所以为了更好的交接,公司B会生成一个秘钥给公司A,公司A在调用公司B接口的时候在配置文件写上秘钥,公司B就知道是公司A的人就可以把用户信息给公司A了。配置文件是可以加密,也可以放到远程的,即使黑客拿到了源代码也看不到配置信息里面的内容,但是如果写在了代码里面可能就会暴露非常危险。在配置信息中调用秘钥效率高,成本低,也是有安全性的。
4、用于发现和定位问题的普通日志和异常日志等
可以配置日志和异常信息,代码程序报错可以定位到异常信息,来排查问题的关键日志。
Spring Boot 的配置文件有两种格式
这两个都是配置文件,当前面的名字是 application
的时候,当 Spring Boot 项目启动的时候就会去读取配置文件里面的信息,当然也可以设置其他名字都可以,只不过不是 application
的话,Spring Boot 项目启动的时候,并不会直接去读取配置文件;别问为什么问就是 Spring Boot 的约定,它设计原则就是约定大于配置
properties 和 yml 它两都是配置文件,区别在于他们是两个不同时代的产物,properties 是老板,也就是 Spring Boot 项目默认文件格式,yml 是属于新版,它两就是版本之间的差异。
特别说明:
1、当两个配置文件都放在 Spring Boot 项目中的时候,Spring Boot 会优先以 .properties 配置为主,也就是说 .properties 的优先级较高,先加载完 .properties 也会再加载 .yml 配置文件。
这里提一嘴,虽然 .properties 优先级高,但是推荐使用 .yml 文件,后面会说明优缺点。
2、虽然说可以两个位置文件可以共存,但在实际业务的时候使用一种配置文件的方式就行,这样会更好的维护,也会降低出错率。
当两个文件共存的时候 .properties 的配置文件全部注解了,启动类会报错启动不起来。要么不动里面的代码,要么删除其中一个配置文件。
社区版的.properties写配置文件的时候是没有代码提示的(yml有),安装插件是为了更好更方便的写代码,建议还是装上插件。
server.port=9999
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/javabookmanage?characterEncoding=utf8&useSSL=false"
spring.datasource.username=root
spring.datasource.password=0123456789
# 假如读取腾讯视频秘钥
Tengxun.token=tengxunshiping
.properties 是以键值对的形式配置的,key 和 value 之间使用 “=” 连接,这里有个注意点等号后面和代码写完的最后面都不要加“空格”,等号后面加“空格”会报错,代码后面加“空格”虽说可以执行但是当是密码的时候系统会再最后自动加上“空格”这样就会连接不了数据库。
.propereties 还有个缺点是后面三段
spring.datasource
会显得很冗余,但是有必须这样写。
要读取配置文件信息的话需要一个新的注解 @Value
,它是专门读取配置文件里面的 key ,但是里面的语法要求加 ${}
,完整 @Value("${key}")
,这样 Spring Boot 才能读取配置文件里面的 key。
@Controller
@RequestMapping("/index")
public class HelloController {
@Value("${Tengxun.token}") // @Value 是专门读取配置文件 key 【key=Tengxun.token】
private String tengxunToken;
@RequestMapping("/tengxun") // localhost:9999/index/tengxun
@ResponseBody
public String getTengXunToken() {
return tengxunToken;
}
注意:这里面 @Value 必须这样格式要求写,还有方法也一定要加上 @ResponseBody ,当然你也可以把 @ResponseBody 加载类上面,这样避免忘记。
得出的结果就是:tengxunshiping ,把配置文件里面的 key(Tengxun.token)的 value 读取出来。
.properties 的缺点分析:
1、代码可能会显得冗余,和大量重复;
2、细节“空格”不能加,很多时候可能不小心加了,编程的时候也不会注意到,最后报错也不知道哪里错了。
为了解决冗余的问题,那么 yml 文件就会简洁一些。
YAML (YAML Ain’t a Markup Language)YAML不是一种标记语言翻译成中文是“另一种标记语言”,yml 是YAML的缩写,通常以.yml为后缀的文件,是一种直观的能够被电脑识别的数据序列化格式,并且容易被人类阅读。
1、可读性更高
2、写法更简洁
3、可以表述更加复杂的数据结构:数组,对象…
4、通用性更好,可以跨语言,不止使用在 java 中,python,golang…都可以使用
yml为树形配置文件,它基础语法是“key: value”,注意 key 和 value 之间是以冒号+空格组成,空格不可省略。
server:
port: 9999
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3360/java101
username: root
password: 0123456789
yml 于 properties 的对比:
yml 除了一些规定死的配置文件语法外,其他的亦可以自己设置。
# 字符串
string:
value: 你好Spring Boot
# 整数,可以是一级亦可以是二级
int: 100
# 代表 null 的意思,他是有这个值,只不过这个值里面什么都没有
mynull:
value: ~
yml 的读取配置文件的方式也是用 @Value
注解来读取,与 .properties
读取配置信息一样。
@Controller
@ResponseBody
public class ReadConfigController {
@Value("${string.value}")
private String myString;
@Value("${int}")
private int myint;
@Value("${mynull.value}")
private Object myNull;
@RequestMapping("/mynull") // localhost:9999/mynull
public Object myNull() {
return myNull;
}
@RequestMapping("/myint") // localhost:9999/myint
public int getMyint() {
return myint;
}
@RequestMapping("/mystring")// localhost:9999/mystring
public String getMyString() {
return myString;
}
}
将对象写入 yml 中:
# 配置对象 写法一:
student:
id: 1
age: 18
name: java
# 写法二:
student2: { id: 2,age: 20,name: python } # 中间空格是要加上的,一定不能省略
读取对象的时候就不能使用 @Value
来读取了,按逻辑来说的话也是可以用 @Value
一个一个来读取,但是一般对象里面的属性非常的多一个一个读取显然是不可能的,这时候就需要创建一个对象A,使用 @ConfigurationProperties
来获取配置文件对象里面的数据注入到对象A中。
@ConfigurationProperties
里面的参数 prefix 是用来选择配置文件里面用的具体哪一个对象,因为配置文件里面会有多个对象。
使用注解 @Component 把对象注入 Spring 容器里面,之后再使用 @Autowired/@Resource 读取 Spring 容器里面的对象,之后就可以对象里面的属性了。
@Controller
@ResponseBody
@RequestMapping("/stu")
public class StudentController {
@Autowired
private Student student;
@RequestMapping("/id") // localhost:9999/stu/id
public int getId() {
return student.getId();
}
}
# 数组 写法一;
listtypes:
name:
- java
- python
- c++
# 写法二:
listtypes2: { name: [ php,golang,c# ] }
代码里面的“-”后面的空格也是不能省去的 ,写法二也是同样的道理。
以上是伪代码实例,里面的属性名称必须要对应。
数组的读取也是和对象的读取是一样的,使用注解 @ConfigurationProperties
来读取,方法步骤都是一样的。
具体实现:
1、创建list对象
@Component
@ConfigurationProperties(prefix = "listtypes") //也是可以直接写成(“listtypes”)
public class ListTypes {
List<String> name;
public List<String> getName() {
return name;
}
public void setName(List<String> name) {
this.name = name;
}
}
这里的 name 和 yml 里面的属性 name 要一致,set 不能省去。
2、注入list对象到当前类中,拿去list对象属性。
@Controller
@ResponseBody
@RequestMapping("/listconf")
public class ListConfigController {
@Resource
private ListTypes listTypes;
@RequestMapping("/getlist") // localhost:9999/listconf/getlist
public void getList() {
// System.out.println(listTypes.getName());
System.out.println(listTypes.getName().get(0));
}
}
这里面的 get()
是数组的下标,你想拿数组中的那一个值就指定下标.
mystr:
value: 你好 \n 世界
value2: '你好 \n 世界'
value3: "你好 \n 世界"
从上诉结果可以看到:
总结: