SpringBoot基础篇
SpringBoot基础篇
文档介绍
文档模块 | 模块介绍 |
---|---|
基础篇 | 能够创建SpringBoot工程 基于SpringBoot实现ssm/ssmp整合 |
应用篇 | 能够掌握SpringBoot程序多环境开发 能够基于Linux系统发布SpringBoot工程 能够解决线上灵活配置SpringBoot工程的需求 能够基于SpringBoot整合任意第三方技术 |
原理篇 | 掌握SpringBoot内部工作流程 理解SpringBoot整合第三方技术的原理 实现自定义开发整合第三方技术的组件 |
快速上手SpringBoot
SpringBoot入门程序开发(基于idea)
SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的初始化搭建以及开发过程。
创建新模块,选择Spring Initiizr,并配置模块相关基础信息
- 第三步点击next时,idea需要联网状态才可以进入到后面那一页,如果不能正常联网,就无法正确到达右面那个设置页
- 第5步选择java版本和计算机上安装的JDK版本匹配即可,但是最低要求为JDK8或以上版本,推荐使用8或11
选择当前模块需要使用过的技术集
- 此处选择SpringBoot默认版本,SpringBoot的版本升级速度很快,但是差别不大,无需纠结,回头可以到配置文件中修改对应的版本
开发控制器类
1
2
3
4
5
6
7
8
9
10//Rest模式
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping
public String getById(){
System.out.println("springboot is running...");
return "springboot is running...";
}
}运行项目创建后自动生成的Application类
使用带main方法的java程序的运行形式来运行程序,运行完毕后,控制台输出上述信息。从开发者角度来看,目前只有两个文件能看到。
pom.xml
这是maven的配置文件,描述了当前工程构建时相应的配置信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
</parent>
<groupId>com.itheima</groupId>
<artifactId>springboot_01_01_quickstart</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>配置中有两个信息需要关注,一个是parent,也就是当前工程继承了另外一个工程,另一个是依赖坐标
Application类
1
2
3
4
5
6@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}这个类功能很简单,就一句代码,前面运行程序就是运行的这个类。
Spring和SpringBoot比较
类配置文件 | Spring | SpringBoot |
---|---|---|
pom文件中的坐标 | 手工添加 | 勾选添加 |
web3.0配置类 | 手工添加 | 无 |
Spring/SpringMVC配置类 | 手工添加 | 无 |
控制器 | 手工添加 | 手工制作 |
一句话总结一下就是能少写就少写,能不写就不写。
总结
- 开发SpringBoot程序可以根据向导进行联网快速制作
- SpringBoot程序需要基于JDK8以上版本进行制作
- SpringBoot程序中需要使用何种功能通过勾选选择技术,也可以手工添加对应要使用的技术
- 运行SpringBoot程序通过运行Application程序入口进行
SpringBoot入门程序制作(基于官网)
点击Spring Initializr后进入到创建SpringBoot程序的界面上,下面是输入信息的过程,和前面的一样,只是界面变了而已,根据自己的要求,在左侧选择对应信息和输入对应的信息即可
右侧的ADD DEPENDENCIES用于选择使用何种技术,和之前勾选的Spring WEB是在做同一件事,仅仅是界面不同而已,点击后打开网页版的技术选择界面
所有信息设置完毕后,点击下面左侧按钮,生成一个文件包
保存后得到一个压缩文件,这个文件打开后就是创建的SpringBoot工程文件夹了
解压缩此文件后,得到工程目录,在Idea中导入即可使用,和之前创建的东西完全一样。下面就可以自己创建一个Controller测试一下是否能用了。
温馨提示
Idea工具中创建SpringBoot工程其实连接的就是SpringBoot的官网,走的就是这个过程,只不过Idea把界面给整合了一下,读取到了Spring官网给的信息,然后展示到了Idea的界面中而已
SpringBoot入门程序制作(基于阿里云)
由于上述项目生成的地址都是国外的,会有被限制访问的可能,所以我们国内还可以通过阿里去创建项目
创建工程时,切换选择starter服务路径,然后手工收入阿里云提供给我们的使用地址即可。地址:http://start.aliyun.com或https://start.aliyun.com
阿里为了便于自己开发使用,因此在依赖坐标中添加了一些阿里相关的技术,也是为了推广自己的技术吧,所以在依赖选择列表中,你有了更多的选择。不过有一点需要说清楚,阿里云地址默认创建的SpringBoot工程版本是2.4.1,所以如果你想更换其他的版本,创建项目后手工修改即可,别忘了刷新一下,加载新版本信息
在Idea中隐藏指定文件/文件夹
创建SpringBoot工程时,使用SpringBoot向导也好,阿里云也罢,其实都是为了一个目的,得到一个标准的SpringBoot工程文件结构。这个时候就有新的问题出现了,标准的工程结构中包含了一些未知的文件夹,在开发的时候看起来特别别扭。
处理方案无外乎两种,如果你对每一个文件/目录足够了解,没有用的完全可以删除掉,或者不删除,但是看着别扭,就设置文件为看不到就行了。删除不说了,直接Delete掉就好了,我们来说说如何隐藏指定的文件或文件夹信息。
打开设置,【Files】-> 【Setting】
打开文件类型设置界面,【Editor】→【File Types】→【Ignored Files and Folders】,忽略文件或文件夹显示
添加你要隐藏的文件名称或文件夹名称,可以使用*号通配符,表示任意,设置完毕即可
SpringBoot入门制作(手动创建)
创建工程时,选择手工创建Maven工程
参照标准SpringBoot工程的pom文件,书写自己的pom文件即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
</parent>
<groupId>com.itheima</groupId>
<artifactId>springboot_01_04_quickstart</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>之前运行SpringBoot工程需要一个类,这个缺不了,自己手写一个就行了,建议按照之前的目录结构来创建。类名可以自定义,关联的名称一切修改即可
1
2
3
4
5
6@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(<Application.class);
}
}- 类上面的注解@SpringBootApplication千万别丢了,这个是核心
- 类名可以自定义,只要保障下面代码中使用的类名和你自己定义的名称一样即可,也就是run方法中的那个class对应的名称
下面就可以自己创建一个Controller测试一下是否能用了,和之前没有差别了
SpringBoot简介
- 起步依赖(简化依赖配置)
- 依赖配置的书写简化就是靠这个起步依赖达成的
- 自动配置(简化常用工程相关配置)
- 配置过于繁琐,使用自动配置就可以做响应的简化
- 辅助功能(内置服务器….)
- 除了上面的功能,其实SpringBoot程序还有其他的一些优势,比如我们没有配置Tomcat服务器,但是能正常运行,这是SpringBoot程序的一个可以感知到的功能,也是SpringBoot的辅助功能之一
parent
开发者在进行开发时,对依赖版本的选择具有固定的搭配格式,并且这些依赖版本的选择还不能乱搭配。
比如A技术的2.0版与B技术的3.5版可以合作在一起,但是和B技术的3.7版合并使用时就有冲突。
SpringBoot于是将所有的技术版本的常见使用方案都给开发者整理了出来,以后开发者使用时直接用它提供的版本方案,就不用担心冲突问题了,相当于SpringBoot做了无数个技术版本搭配的列表,这个技术搭配列表的名字叫做parent
parent自身具有很多个版本,每个parent版本中包含有几百个其他技术的版本号,不同的parent间使用的各种技术的版本号有可能会发生变化。当开发者使用某些技术时,直接使用SpringBoot提供的parent就行了,由parent帮助开发者统一的进行各种技术的版本管理
parent仅仅帮我们进行版本管理,它不负责帮你导入坐标,说白了用什么还是你自己定,只不过版本不需要你管理了。整体上来说,使用parent可以帮助开发者进行版本的统一管理
关注:parent定义出来以后,并不是直接使用的,仅仅给了开发者一个说明书,但是并没有实际使用,这个一定要确认清楚
查看SpringBoot配置源码
在项目中的pom.xml继承了一个坐标
1
2
3
4
5<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
</parent>打开后可以查阅到其中又继承了一个坐标
1
2
3
4
5<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.4</version>
</parent>这个坐标中定义了两组信息,第一组是各式各样的依赖版本号属性,下面列出依赖版本属性的局部,可以看的出来,定义了若干个技术的依赖版本号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<properties>
<activemq.version>5.16.3</activemq.version>
<aspectj.version>1.9.7</aspectj.version>
<assertj.version>3.19.0</assertj.version>
<commons-codec.version>1.15</commons-codec.version>
<commons-dbcp2.version>2.8.0</commons-dbcp2.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<commons-pool.version>1.6</commons-pool.version>
<commons-pool2.version>2.9.0</commons-pool2.version>
<h2.version>1.4.200</h2.version>
<hibernate.version>5.4.32.Final</hibernate.version>
<hibernate-validator.version>6.2.0.Final</hibernate-validator.version>
<httpclient.version>4.5.13</httpclient.version>
<jackson-bom.version>2.12.4</jackson-bom.version>
<javax-jms.version>2.0.1</javax-jms.version>
<javax-json.version>1.1.4</javax-json.version>
<javax-websocket.version>1.1</javax-websocket.version>
<jetty-el.version>9.0.48</jetty-el.version>
<junit.version>4.13.2</junit.version>
</properties>第二组是各式各样的的依赖坐标信息,可以看出依赖坐标定义中没有具体的依赖版本号,而是引用了第一组信息中定义的依赖版本属性值
1
2
3
4
5
6
7
8
9
10
11
12
13
14<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
</dependencyManagement>关注:上面的依赖坐标定义是出现在
标签中的,其实是对引用坐标的依赖管理,并不是实际使用的坐标。因此当你的项目中继承了这组parent信息后,在不使用对应坐标的情况下,前面的这组定义是不会具体导入某个依赖的 关注:因为在maven中继承机会只有一次,上述继承的格式还可以切换成导入的形式进行,并且在阿里云的starter创建工程时就使用了此种形式
1
2
3
4
5
6
7
8
9
10
11<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
总结
- 开发SpringBoot程序要继承spring-boot-starter-parent
- spring-boot-starter-parent中定义了若干个依赖管理
- 继承parent模块可以避免多个依赖使用相同技术时出现依赖版本冲突
- 继承parent的形式也可以采用引入依赖的形式实现效果
starter
开发者在实际开发时,对于依赖坐标的使用往往都有一些固定的组合方式,比如使用spring-webmvc就一定要使用spring-web。
SpringBoot一看这种情况,把所有的技术使用的固定搭配格式都给开发出来,以后你用某个技术,就不用一次写一堆依赖了,对于这样的固定技术搭配,SpringBoot给它起了个名字叫做starter。
starter定义了使用某种技术时对于依赖的固定搭配格式,也是一种最佳解决方案,使用starter可以帮助开发者减少依赖配置
从添加web功能分析
项目中的pom.xml定义了使用SpringMVC技术,但是并没有写SpringMVC的坐标,而是添加了一个名字中包含starter的依赖
1
2
3
4<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>在spring-boot-starter-web中又定义了若干个具体依赖的坐标
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.9</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
<scope>compile</scope>
</dependency>
</dependencies> 之前提到过开发SpringMVC程序需要导入spring-webmvc的坐标和spring整合web开发的坐标,就是上面这组坐标中的最后两个了。
但是我们发现除了这两个还有其他的,比如第二个,叫做spring-boot-starter-json。看名称就知道,这个是与json有关的坐标了,但是看名字发现和最后两个又不太一样,它的名字中也有starter,打开看看里面有什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.9</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.12.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.12.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
<version>2.12.4</version>
<scope>compile</scope>
</dependency>
</dependencies> 我们可以发现,这个starter中又包含了若干个坐标,其实就是使用SpringMVC开发通常都会使用到Json,使用json又离不开这里面定义的这些坐标。
你仔细看完会发现,里面有一些你没用过的。的确会出现这种过量导入的可能性,没关系,可以通过maven中的排除依赖剔除掉一部分。不过你不管它也没事,大不了就是过量导入呗。
温馨提示
SpringBoot官方给出了好多个starter的定义,方便我们使用,而且名称都是如下格式
1 |
|
所以以后见了spring-boot-starter-aaa这样的名字,这就是SpringBoot官方给出的starter定义。非官方定义的也是有的。
总结
- 开发SpringBoot程序需要导入坐标时通常导入对应的starter
- 每个不同的starter根据功能不同,通常包含多个依赖坐标
- 使用starter可以实现快速配置的效果,达到简化配置的目的
starter和parent的区别
朦朦胧胧中感觉starter与parent好像都是帮助我们简化配置的,但是功能又不一样,梳理一下
- starter是一个坐标中定了若干个坐标,以前写多个的,现在写一个,是用来减少依赖配置的书写量的
- parent是定义了几百个依赖版本号,以前写依赖需要自己手工控制版本,现在由SpringBoot统一管理,这样就不存在版本冲突了,是用来减少依赖冲突的
实际开发应用方式
实际开发中如果需要用什么技术,先去找有没有这个技术对应的starter
- 如果有对应的starter,直接写starter,而且无需指定版本,版本由parent提供
- 如果没有对应的starter,手写坐标即可
实际开发中如果发现坐标出现了冲突现象,确认你要使用的可行的版本号,使用手工书写的方式添加对应依赖,覆盖SpringBoot提供给我们的配置管理
方式一:直接写坐标
方式二:覆盖
中定义的版本号,就是下面这堆东西了,哪个冲突了覆盖哪个就OK了 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<properties>
<activemq.version>5.16.3</activemq.version>
<aspectj.version>1.9.7</aspectj.version>
<assertj.version>3.19.0</assertj.version>
<commons-codec.version>1.15</commons-codec.version>
<commons-dbcp2.version>2.8.0</commons-dbcp2.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<commons-pool.version>1.6</commons-pool.version>
<commons-pool2.version>2.9.0</commons-pool2.version>
<h2.version>1.4.200</h2.version>
<hibernate.version>5.4.32.Final</hibernate.version>
<hibernate-validator.version>6.2.0.Final</hibernate-validator.version>
<httpclient.version>4.5.13</httpclient.version>
<jackson-bom.version>2.12.4</jackson-bom.version>
<javax-jms.version>2.0.1</javax-jms.version>
<javax-json.version>1.1.4</javax-json.version>
<javax-websocket.version>1.1</javax-websocket.version>
<jetty-el.version>9.0.48</jetty-el.version>
<junit.version>4.13.2</junit.version>
</properties>
引导类
目前程序运行的入口就是SpringBoot工程创建时自带的那个类了,带有main方法的那个类,运行这个类就可以启动SpringBoot工程的运行,这个类在SpringBoot程序中是所有功能的入口,称这个类为引导类。。
当前这个类运行后就会产生一个Spring容器对象,并且可以将这个对象保存起来,通过容器对象直接操作Bean
1 |
|
作为一个引导类最典型的特征就是当前类上方声明了一个注解@SpringBootApplication
总结
- SpringBoot工程提供引导类用来启动程序
- SpringBoot工程启动后创建并初始化Spring容器
思考
程序现在已经运行了,通过引导类的main方法运行了起来。但是运行java程序不应该是执行完就结束了吗?但是我们现在明显是启动了一个web服务器啊,不然网页怎么能正常访问呢?这个服务器是在哪里写的呢?
内嵌Tomcat
创建SpringBoot时勾选Spring-web的功能,并且导入了对应的starter,在这个里面就集成了web服务器。
由于这个功能不属于程序的主体功能,可用可不用,于是乎SpringBoot将其定位成辅助功能
内嵌Tomcat定义位置
打开查看web的starter导入了哪些东西
1 |
|
第三个依赖就是这个tomcat对应的东西了,居然也是一个starter,再打开看看
1 |
|
这里面有一个核心的坐标,tomcat-embed-core,叫做tomcat内嵌核心。就是这个东西把tomcat功能引入到了我们的程序中。
内嵌Tomcat运行原理
Tomcat服务器是一款软件,而且是一款使用java语言开发的软件。既然是使用java语言开发的,运行的时候肯定符合java程序运行的原理,java程序运行靠的对象,如果是对象,那Spring容器是用来管理对象的,所以tomcat服务器运行其实是以对象的形式在Spring容器中运行的
具体运行的是上面提到的Tomcat内嵌核心
1 |
|
那既然是个对象,如果把这个对象从Spring容器中去掉是不是就没有web服务器的功能呢?是这样的,通过依赖排除可以去掉这个web服务器功能
1 |
|
更换内嵌Tomcat
根据SpringBoot的工作机制,用什么技术,加入什么依赖就行了。SpringBoot提供了3款内置的服务器
tomcat(默认):apache出品,粉丝多,应用面广,负载了若干较重的组件
jetty:更轻量级,负载性能远不及tomcat
undertow:负载性能勉强跑赢tomcat
想用哪个,加个坐标就OK。前提是把tomcat排除掉,因为tomcat是默认加载的。
1 |
|
现在就已经成功替换了web服务器,核心思想就是用什么加入对应坐标就可以了。如果有starter,优先使用starter。
总结
- 内嵌Tomcat服务器是SpringBoot辅助功能之一
- 内嵌Tomcat工作原理是将Tomcat服务器作为对象运行,并将该对象交给Spring容器管理
- 变更内嵌服务器思想是去除现有服务器,添加全新的服务器
SpringBoot基础配置
复制模块
- 在工作空间中复制对应工程,并修改工程名称
- 删除与Idea相关配置文件,仅保留src目录与pom.xml文件
- 修改pom.xml文件中的artifactId与新工程/模块名相同
- 删除name标签
- 保留备份工程供后期使用。
属性配置
SpringBoot通过配置文件application.properties就可以修改默认的配置。
properties格式的文件书写规范是key=value
下面将设置下服务的端口号为80
1 |
|
其实到这里我们应该得到如下三个信息
- SpringBoot程序可以在application.properties文件中进行属性配置
- application.properties文件中只要输入要配置的属性关键字就可以根据提示进行设置
- SpringBoot将配置信息集中在一个文件中写,不管你是服务器的配置,还是数据库的配置,总之都写在一起,逃离一个项目十几种配置文件格式的尴尬局面
关闭运行日志图标
1 |
|
设置运行日志的显示级别
1 |
|
对应配置项
打开SpringBoot的官网,找到SpringBoot官方文档,打开查看附录中的Application Properties就可以获取到对应的配置项了
在pom中注释掉导入的spring-boot-starter-web,然后刷新工程,你会发现配置的提示消失了。所以是设定使用了什么技术才能做什么配置
总结
- SpringBoot中导入对应starter后,提供对应配置属性
- 书写SpringBoot配置采用关键字+提示形式书写
配置文件分类
properties格式(application.properties是传统格式/默认格式)
1
server.port=80
yml格式(application.yml是主流格式)
1
2server:
port: 81yaml格式(application.yaml)
1
2server:
port: 82
仔细看会发现yml格式和yaml格式除了文件名后缀不一样,格式完全一样,是这样的,yml和yaml文件格式就是一模一样的,只是文件后缀不同,所以可以合并成一种格式来看
配置文件优先级
按照上述三个配置文件去配置后,启动后发现目前的启动端口为80,把80对应的文件删除掉,然后再启动,现在端口又改成了81。现在我们就已经知道了3个文件的加载优先顺序
1 |
|
最后我们把配置文件内容给修改一下
- application.properties(properties格式)
1 |
|
- application.yml(yml格式)
1 |
|
- application.yaml(yaml格式)
1 |
|
我们发现不仅端口生效了,最终显示80,同时其他两条配置也生效了,看来每个配置文件中的项都会生效,只不过如果多个配置文件中有相同类型的配置会优先级高的文件覆盖优先级的文件中的配置。如果配置项不同的话,那所有的配置项都会生效。
总结
- 配置文件间的加载优先级 properties(最高)> yml > yaml(最低)
- 不同配置文件中相同配置按照加载优先级相互覆盖,不同配置文件中不同配置全部保留
自动提示功能消失解决方案
大体原因有如下2种:
Idea认为你现在写配置的文件不是个配置文件,所以拒绝给你提供提示功能
Idea认定你是合理的配置文件,但是Idea加载不到对应的提示信息
这里我们主要解决第一个现象,第二种现象到原理篇再讲解。第一种现象的解决方式如下
具体设置
打开设置,【Files】→【Project Structure…】
在弹出窗口中左侧选择【Facets】,右侧选中Spring路径下对应的模块名称,也就是你自动提示功能消失的那个模块
点击Customize Spring Boot按钮,此时可以看到当前模块对应的配置文件是哪些了。如果没有你想要称为配置文件的文件格式,就有可能无法弹出提示
选择添加配置文件,然后选中要作为配置文件的具体文件就OK了
yaml文件
SpringBoot的配置以后主要使用yml结尾的这种文件格式,并且在书写时可以通过提示的形式加载正确的格式。
YAML(YAML Ain’t Markup Language),一种数据序列化格式。具有容易阅读、容易与脚本语言交互、以数据为核心,重数据轻格式的特点。常见的文件扩展名有两种:
- .yml格式(主流)
- .yaml格式
语法格式要求
- 大小写敏感
- 属性层级关系使用多行描述,每行结尾使用冒号结束
- 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
- 属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
- #号表示注释
核心的一条规则要记住,数据前面要加空格与冒号隔开
此外,yaml格式中也可以表示数组,在属性名书写位置的下方使用减号作为数据开始符号,每行书写一个数据,减号与数据间空格分隔
1 |
|
yaml数据读取
对于yaml文件中的数据,其实你就可以想象成这就是一个小型的数据库,里面保存有若干数据,每个数据都有一个独立的名字,如果你想读取里面的数据,肯定是支持的,下面就介绍3种读取数据的方式
读取单一数据
yaml中保存的单个数据,可以使用Spring中的注解直接读取,使用@Value可以读取单个数据,属性名引用方式:${一级属性名.二级属性名……}
记得使用@Value注解时,要将该注入写在某一个指定的Spring管控的bean的属性名上方。现在就可以读取到对应的单一数据行了
读取全部数据
读取单一数据可以解决读取数据的问题,但是如果定义的数据量过大,这么一个一个书写肯定会累死人的,SpringBoot提供了一个对象,能够把所有的数据都封装到这一个对象中,这个对象叫做Environment,使用自动装配注解可以将所有的yaml数据封装到这个对象中
数据封装到了Environment对象中,获取属性时,通过Environment的接口操作进行,具体方法时getProperties(String),参数填写属性名即可
读取对象数据
单一数据读取书写比较繁琐,全数据封装又封装的太厉害了,每次拿数据还要一个一个的getProperties(),总之用起来都不是很舒服。由于Java是一个面向对象的语言,很多情况下,我们会将一组数据封装成一个对象。SpringBoot也提供了可以将一组yaml对象数据封装一个Java对象的操作。
首先定义一个对象,并将该对象纳入Spring管控的范围,也就是定义成一个bean,然后使用注解@ConfigurationProperties指定该对象加载哪一组yaml中配置的信息。
这个@ConfigurationProperties必须告诉他加载的数据前缀是什么,这样当前前缀下的所有属性就封装到这个对象中。记得数据属性名要与对象的变量名一一对应啊,不然没法封装。
其实以后如果你要定义一组数据自己使用,就可以先写一个对象,然后定义好属性,下面到配置中根据这个格式书写即可。
总结
- 使用@ConfigurationProperties注解绑定配置信息到封装类中
- 封装类需要定义为Spring管理的bean,否则无法进行属性注入
yaml文件中的数据引用
如果你在书写yaml数据时,经常出现如下现象,比如很多个文件都具有相同的目录前缀
1 |
|
或者
1 |
|
这个时候你可以使用引用格式来定义数据,其实就是搞了个变量名,然后引用变量了,格式如下:
1 |
|
还有一个注意事项,在书写字符串时,如果需要使用转义字符,需要将数据字符串使用双引号包裹起来
1 |
|
基于SpringBoot实现SSMP整合
- 整合JUnit
- 整合MyBatis
- 整合MyBatis-Plus
- 整合Druid
整合JUnit
Spring整合JUnit的制作方式
1 |
|
其中核心代码是前两个注解
- @RunWith是设置Spring专用于测试的类运行器,简单说就是Spring程序执行程序有自己的一套独立的运行程序的方式,不能使用JUnit提供的类运行方式了,必须指定一下,但是格式是固定的
- @ContextConfiguration是用来设置Spring核心配置文件或配置类的,简单说就是加载Spring的环境你要告诉Spring具体的环境配置是在哪里写的,虽然每次加载的文件都有可能不同,但是仔细想想,如果文件名是固定的,这个貌似也是一个固定格式
- SpringBoot就抓住上述两条没有技术含量的内容书写进行开发简化,能走默认值的走默认值,能不写的就不写,具体格式如下
1 |
|
使用一个注解@SpringBootTest替换了前面两个注解。至于内部是怎么回事?和之前一样,只不过都走默认值。
加载的配置类或者配置文件,就是我们前面启动程序使用的引导类。如果想手工指定引导类有两种方式
使用属性的形式进行,在注解@SpringBootTest中添加classes属性指定配置类
1
2
3
4
5
6
7
8
9
10
11
12@SpringBootTest(classes = Springboot04JunitApplication.class)
class Springboot04JunitApplicationTests {
//注入你要测试的对象
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
//执行要测试的对象对应的方法
bookDao.save();
System.out.println("two...");
}
}回归原始配置方式,仍然使用@ContextConfiguration注解进行,效果是一样的
1
2
3
4
5
6
7
8
9
10
11
12
13@SpringBootTest
@ContextConfiguration(classes = Springboot04JunitApplication.class)
class Springboot04JunitApplicationTests {
//注入你要测试的对象
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
//执行要测试的对象对应的方法
bookDao.save();
System.out.println("two...");
}
}
整合Mybatis
原始整合(以配置类的形式)
导入坐标
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--1.导入mybatis与spring整合的jar包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!--导入spring操作数据库必选的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>Spring核心配置
1
2
3
4
5@Configuration
@ComponentScan("com.zhuixun")
@PropertySource("jdbc.properties")
public class SpringConfig {
}Mybatis要交给Spring接管的bean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//定义mybatis专用的配置类
@Configuration
public class MyBatisConfig {
// 定义创建SqlSessionFactory对应的bean
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
//SqlSessionFactoryBean是由mybatis-spring包提供的,专用于整合用的对象
SqlSessionFactoryBean sfb = new SqlSessionFactoryBean();
//设置数据源替代原始配置中的environments的配置
sfb.setDataSource(dataSource);
//设置类型别名替代原始配置中的typeAliases的配置
sfb.setTypeAliasesPackage("com.itheima.domain");
return sfb;
}
// 定义加载所有的映射配置
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.itheima.dao");
return msc;
}
}数据源对应的bean,此处使用Druid数据源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21@Configuration
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
@Bean("dataSource")
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}数据库连接信息(properties格式)
1
2
3
4jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?useSSL=false
jdbc.username=root
jdbc.password=root
SpringBoot整合MyBaits格式
创建模块时勾选要使用的技术,MyBatis,由于要操作数据库,还要勾选对应数据库
或者手工导入对应技术的starter,和对应数据库的坐标
1 |
|
配置数据源相关信息,没有这个信息你连接哪个数据库都不知道
1
2
3
4
5
6
7#2.配置相关信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db
username: root
password: root
下面就可以写一下MyBatis程序运行需要的Dao(或者Mapper)就可以运行了
实体类
1 |
|
映射接口(Dao)
1 |
|
测试类
1 |
|
注意
Mysql驱动使用的是8x版本,8以后要求强制配置时区,如果不设置会出问题。解决方案很简单,驱动url上面添加上对应设置就行了
1 |
|
这里设置的UTC是全球标准时间,你也可以理解为是英国时间,中国处在东八区,需要在这个基础上加上8小时,这样才能和中国地区的时间对应的,也可以修改配置不写UTC,写Asia/Shanghai也可以解决这个问题。
1 |
|
如果不想每次都设置这个东西,也可以去修改mysql中的配置文件mysql.ini,在mysqld项中添加default-time-zone=+8:00也可以解决这个问题。其实方式方法很多,这里就说这么多吧。
此外在运行程序时还会给出一个提示,说数据库驱动过时的警告,根据提示修改配置即可,弃用com.mysql.jdbc.Driver,换用com.mysql.cj.jdbc.Driver。
1 |
|
总结
整合操作需要勾选MyBatis技术,也就是导入MyBatis对应的starter
数据库连接相关信息转换成配置
数据库SQL映射需要添加@Mapper被容器识别到
MySQL 8.X驱动强制要求设置时区
- 修改url,添加serverTimezone设定
- 修改MySQL数据库配置
驱动类过时,提醒更换为com.mysql.cj.jdbc.Driver
整合Mybatis-Plus
导入对应技术的starter坐标
1
2
3
4
5<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>这个坐标的名字书写比较特殊,是第三方技术名称在前,boot和starter在后。此处简单提一下命名规范
starter所属 命名规则 示例 官方提供 spring-boot-starter-技术名称 spring-boot-starter-web spring-boot-starter-test 第三方提供 第三方技术名称-spring-boot-starter druid-spring-boot-starter 第三方提供 第三方技术名称-boot-starter(第三方技术名称过长,简化命名) mybatis-plus-boot-starter 根据对应技术的要求做配置
1
2
3
4
5
6
7#2.配置相关信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db
username: root
password: root剩下的就是写MyBaitsPlus的程序了
映射接口(Dao)
1
2
3@Mapper
public interface BookDao extends BaseMapper<Book> {
}核心在于Dao接口继承了一个BaseMapper的接口,这个接口中帮助开发者预定了若干个常用的API接口,简化了通用API接口的开发工作。
温馨提示
目前数据库的表名定义规则是tbl_模块名称,为了能和实体类相对应,需要做一个配置,配置application.yml文件,添加如下配置即可,设置所有表名的通用前缀名
1 |
|
整合Druid
前面整合MyBatis和MP的时候,使用的数据源对象都是SpringBoot默认的数据源对象,下面我们手工控制一下,自己指定了一个数据源对象,Druid。
在没有指定数据源时,我们的配置如下
1 |
|
此时虽然没有指定数据源,但是根据SpringBoot的德行,肯定帮我们选了一个它认为最好的数据源对象,这就是HiKari。通过启动日志可以查看到对应的身影。
1 |
|
如果需要更换数据源,其实只需要两步即可。
导入对应的技术坐标
1
2
3
4
5
6
7<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
</dependencies>配置使用指定的数据源类型
1
2
3
4
5
6
7spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
如果上面这种通用格式就不能使用了,需要配置对应数据源的特有配置,需要导入对应的starter,进行相应的配置即可。
导入对应的starter
1
2
3
4
5
6
7<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
</dependencies>修改配置
1
2
3
4
5
6
7spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: root注意观察,配置项中,在datasource下面并不是直接配置url这些属性的,而是先配置了一个druid节点,然后再配置的url这些东西。言外之意,url这个属性时druid下面的属性,除了这4个常规配置外,还有druid专用的其他配置。通过提示功能可以打开druid相关的配置查阅