1. SpringBoot概述
1.1 约定大于配置
- 约定优于配置(Convention over Configuration),又称按约定编程,是一种软件设计范式。
本质上是说,系统、类库或框架应该假定合理的默认值,而非要求提供不必要的配置。比如说模型中有
一个名为User的类,那么数据库中对应的表就会默认命名为user。 - 只有在偏离这一个约定的时候,例如 想要将该表命名为person,才需要写有关这个名字的配置。
- 比如平时架构师搭建项目就是限制软件开发随便写代码,制定出一套规范,让开发人员按统一的要求进
行开发编码测试之类的,这样就加强了开发效率与审查代码效率。 - 所以说写代码的时候就需要按要求命名,这样统一规范的代码就有良好的可读性与维护性了约定优于配置简单来理解,就是遵循约定
1.2 Spring优缺点
1.2.1 优点
- Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品。无需开发重量级的Enterprise Java Bean(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(Plain Old Java Object,POJO)实现了EJB的功能
1.2.2 缺点
- 虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring用XML配置,而且是很
多XML配 置。 - Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML
配置。Spring 3.0引入 了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。 - 所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切
换,所以编写配置挤占了编写应用程序逻辑的时间。和所有框架一样,Spring实用,但与此同时它要求
的回报也不少。 - 除此之外,项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,
而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题
就会严重阻碍项目的开发进度 - SSM整合:Spring、Spring MVC、Mybatis、Spring-Mybatis整合包、数据库驱动,引入依赖的数量繁
多、容易存在版本冲突
1.3 Spring解决的问题
- SpringBoot对上述Spring的缺点进行的改善和优化,基于约定优于配置的思想,可以让开发人员不必在
配置与逻辑 业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的
效率,一定程度上缩短 了项目周期
1.3.1 起步依赖
- 起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依
赖,这些东西加在一起即支持某项功能。
简单的说,起步依赖就是将具备某种功能的依赖坐标打包到一起,并提供一些默认的功能
1.3.2 自动配置
- springboot的自动配置,指的是springboot,会自动将一些配置类的bean注册进ioc容器,我们可以需
要的地方使用@autowired或者@resource等注解来使用它。 - 自动的表现形式就是我们只需要引我们想用功能的包,相关的配置我们完全不用管,springboot会自
动注入这些配置bean,我们直接使用这些bean即可 - springboot: 简单、快速、方便地搭建项目;对主流开发框架的无配置集成;极大提高了开发、部署效率
2. Spring入门案例
2.1 创建基础项目
- 创建 SpringBoot 项目
2.2 依赖配置
-
maven配置
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--引入Spring Web及Spring MVC相关的依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <!--可以将project打包为一个可以执行的jar--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
-
所用的springBoot项目都会直接或者间接的继承
spring-boot-starter-parent
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
-
指定项目的编码格式为UTF-8
-
指定JDK版本为1.8
-
对项目依赖的版本进行管理,当前项目再引入其他常用的依赖时就需要再指定版本号,避免版本 冲突的问
-
默认的资源过滤和插件管理, 点击maven配置中的
spring-boot-starter-parent
可以查看<artifactId>spring-boot-starter-parent</artifactId> <packaging>pom</packaging> <name>spring-boot-starter-parent</name> <description>Parent pom providing dependency and plugin management for applications built with Maven</description> <properties> <java.version>1.8</java.version> <resource.delimiter>@</resource.delimiter> <maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.target>${java.version}</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties>
2.3 启动类
package cn.knightzz.apply;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* SpringBoot的启动类通常放在二级包中,比如:com.lagou.SpringBootDemo1Application
* 因为SpringBoot项目在做包扫描,会扫描启动类所在的包及其子包下的所有内容。
* @SpringBootApplication 标识当前类为SpringBoot项目的启动类
* @author 王天赐
*/
@SpringBootApplication
public class SpringbootApplyApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplyApplication.class, args);
}
}
2.4 Controller
- HelloController
package cn.knightzz.apply.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello";
}
}
- 输入
http://localhost:8080/hello
可以直接访问
2.5 单元测试
2.5.1 基本概述
- 开发中,每当完成一个功能接口或业务方法的编写后,通常都会借助单元测试验证该功能是否正
确。Spring Boot对项目的单元测试提供了很好的支持 - 在使用时,需要提前在项目的pom.xml文件中添加
spring-boot-starter-test
测试依赖启动器,可以通过相关注解实现单元测试
2.5.2 添加配置
-
添加maven配置
<!-- 单元测试--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
-
注意:使用Spring Initializr方式搭建的Spring Boot项目,会自动加入spring-boot-starter-test测试依赖启动器,无需再手动添加
2.5.3 编写单元测试
- 编写单元测试
package cn.knightzz.apply.controller;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.jupiter.api.Assertions.*;
/**
* SpringJUnit4ClassRunner.class:Spring运行环境
* JUnit4.class:JUnit运行环境
* SpringRunner.class:Spring Boot运行环境
* @RunWith(SpringRunner.class) : @RunWith:运行器
* @SpringBootTest : 标记为当前类为SpringBoot测试类,加载项目的ApplicationContext上下文环境
*/
@RunWith(SpringRunner.class)
@SpringBootTest
class HelloControllerTest {
@Autowired
HelloController helloController;
@Test
void hello() {
String hello = helloController.hello();
System.out.println(hello);
}
}
2.6 热部署
2.6.1 基本概述
- 在开发过程中,通常会对一段业务代码不断地修改测试,在修改之后往往需要重启服务,有些服务
需要加载很久才能启动成功,这种不必要的重复操作极大的降低了程序开发效率。为此,Spring Boot框
架专门提供了进行热部署的依赖启动器,用于进行项目热部署,而无需手动重启项目 。 - 热部署:在修改完代码之后,不需要重新启动容器,就可以实现更新。
2.6.2 使用步骤
-
添加spring-boot-devtools热部署依赖启动器
<!-- 引入热部署依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
-
由于使用的是IDEA开发工具,添加热部署依赖后可能没有任何效果,接下来还需要针对IDEA开发
工具进行热部署相关的功能设置
-
IDEA工具热部署设置 :
-
选择IDEA工具界面的【File】->【Settings】选项,打开Compiler面板设置页面
-
选择Build下的Compiler选项,在右侧勾选“Build project automatically”选项将项目设置为自动编译,单击【Apply】→【OK】按钮保存设置
-
找到设置, 勾选下图红框部分 : 当前IDEA版本2021.3
2.6.3 热部署测试
- 启动项目并访问 :
http://localhost:8080/hello
- 在不关闭项目的情况下, 修改 HelloController 的方法的返回值, 然后保存
- 再次刷新可以发现页面值改变
3. SpringBoot配置文件
3.1 全局配置
- 全局配置文件能够对一些默认配置值进行修改。Spring Boot使用一个application.properties或者
application.yaml的文件作为全局配置文件 - 该文件存放在src/main/resource目录或者类路径的/config,一般会选择resource目录。接下来,将针对这两种全局配置文件进行讲解, Spring Boot配置文件的命名及其格式:
- application.properties
- application.yaml
- application.yml
3.2 properties配置文件
-
使用Spring Initializr方式构建Spring Boot项目时,会在resource目录下自动生成一个空的
-
application.properties文件,Spring Boot项目启动时会自动加载application.properties文件。
-
我们可以在application.properties文件中定义Spring Boot项目的相关属性,当然,这些相关属性可以是系统属性、环境变量、命令参数等信息,也可以是自定义配置文件名称和位置
#修改tomcat的版本号 server.port=8888 #定义数据库的连接信息 JdbcTemplate spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/database spring.datasource.username=root spring.datasource.password=123456
3.3 配置文件案例
-
创建 Pet 和 Person 类
-
Pet
public class Pet { private String type; private String name; // set / get }
-
Person
@Component @ConfigurationProperties(prefix = "person") public class Person { private int id; private String name; private List hobby; private String[] family; private Map map; private Pet pet; }
-
application.properties
person.id=1 person.name=张三 person.hobby=阅读,写作 person.family=father,mather person.map.key1=value1 person.map.key2=value2 person.pet.type=dog person.pet.name=哈士奇
-
测试代码
package cn.knightzz.apply.entity; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.bind.annotation.RestController; import static org.junit.jupiter.api.Assertions.*; @RunWith(SpringRunner.class) @SpringBootTest class PersonTest { @Autowired Person person; @Test void personTest(){ System.out.println(person); } }
3.4 SpringBoot中文乱码
3.4.1 项目编码
3.4.2 Tomact和Http编码
-
新版配置
#解决中文乱码 server.tomcat.uri-encoding=UTF-8 server.servlet.encoding.enabled=true server.servlet.encoding.charset=UTF-8 server.servlet.encoding.force=true
-
旧版配置
#解决中文乱码 server.tomcat.uri-encoding=UTF-8 spring.http.encoding.enabled=true spring.http.encoding.charset=UTF-8 spring.http.encoding.force=true
3.5 application.yaml配置文件
3.5.1 基本概念
- YAML文件格式是Spring Boot支持的一种JSON文件格式,相较于传统的Properties配置文件,YAML文
件以数据为核心,是一种更为直观且容易被电脑识别的数据序列化格式。application.yaml配置文件的
工作原理和application.properties是一样的,只不过yaml格式配置文件看起来更简洁一些。 - YAML文件的扩展名可以使用.yml或者.yaml。
3.5.2 普通数据类型
-
application.yml文件使用 key:(空格)value 格式配置属性,使用缩进控制层级关系。
-
当YAML配置文件中配置的属性值为普通数据类型时,可以直接配置对应的属性值,同时对于字符
串类型的属性值,不需要额外添加引号
3.5.3 数组和单列集合
-
value值为数组和单列集合
-
当YAML配置文件中配置的属性值为数组或单列集合类型时,主要有两种书写方式:缩进式写法和行内
式写法。person: hobby: - play - read - sleep
-
或者使用下面的形式
person: hobby: play, read, sleep
-
上述代码中,在YAML配置文件中通过两种缩进式写法对person对象的单列集合(或数组)类型的爱好
hobby赋值为play、read和sleep。其中一种形式为“-(空格)属性值”,另一种形式为多个属性值之前加
英文逗号分隔(注意,最后一个属性值后不要加逗号)。person: hobby: [play,read,sleep]
3.5.4 Map集合和对象
-
value值为Map集合和对象
-
当YAML配置文件中配置的属性值为Map集合或对象类型时,YAML配置文件格式同样可以分为两种书写
方式:缩进式写法和行内式写法。 -
其中,缩进式写法的示例代码如下
person: map: k1: v1 k2: v2
-
对应的行内式写法示例代码如下
person: map: {k1: v1,k2: v2}
-
在YAML配置文件中,配置的属性值为Map集合或对象类型时,缩进式写法的形式按照YAML文件格式编
写即可,而行内式写法的属性值要用大括号“{}”包含。
接下来,在Properties配置文件演示案例基础上,通过配置application.yaml配置文件对Person对象进行赋值,具体使用如下 -
需要说明的是,本次使用application.yaml配置文件进行测试时需要提前将application.properties配置文件中编写的配置注释,这是因为application.properties配置文件会覆盖application.yaml配置文件
3.5.5 配置优先级
-
配置文件的优先级如下: 从低到高
<includes> <include>**/application*.yml</include> <include>**/application*.yaml</include> <include>**/application*.properties</include> </includes>
-
使用Spring Boot全局配置文件设置属性时:
- 如果配置属性是Spring Boot已有属性,例如服务端口server.port,那么Spring Boot内部会自动扫描并读取这些配置文件中的属性值并覆盖默认属性。
- 如果配置的属性是用户自定义属性,例如刚刚自定义的Person实体类属性,还必须在程序中注入这些配
置属性方可生效。 - Spring Boot支持多种注入配置文件属性的方式
3.6 配置文件注解
3.6.1 @ConfigurationProperties
-
Spring Boot提供的
@ConfigurationProperties
注解用来快速、方便地将配置文件中的自定义属性值批量 -
注入到某个Bean对象的多个对应属性中。假设现在有一个配置文件,如果使用
@ConfigurationProperties注入配置文件的属性,示例代码如下: -
实体类
@Component @ConfigurationProperties(prefix = "person") public class Person { private int id; private String name; private List hobby; private String[] family; private Map map; private Pet pet; }
-
配置
person: id: 1 name: 张飞 family: - 父母 - 儿子 hobby: - play - read - sleep map: k1: value1 k2: value2 pet: type: 狗 name: 小猫
-
上述代码使用@Component和@ConfigurationProperties(prefix = “person”)将配置文件中的每个属性映射到person类组件中。
3.6.2 @Value
- @Value注解是Spring框架提供的,用来读取配置文件中的属性值并逐个注入到Bean对象的对应属性
中,Spring Boot框架从Spring框架中对@Value注解进行了默认继承,所以在Spring Boot框架中还可以使用该注解读取和注入配置文件属性值。使用@Value注入属性的示例代码如下
@Component
public class Student {
@Value("${student.id}")
private Integer id;
@Value("${student.name}")
private String name;
// get / set
}
- @Value注解对于包含Map集合、对象以及YAML文件格式的行内式写法的配置文件的属性注入都不支持,如果赋值会出现错误
3.6.3 自定义配置
- spring Boot免除了项目中大部分的手动配置,对于一些特定情况,我们可以通过修改全局配置文
件以适应具体生产环境,可以说,几乎所有的配置都可以写在application.yml文件中,Spring Boot会自动加载全局配置文件从而免除我们手动加载的烦恼。 - 但是,如果我们自定义配置文件,Spring Boot是无法识别这些配置文件的,此时就需要我们手动加载。
3.6.4 @PropertySource
-
对于这种加载自定义配置文件的需求,可以使用@PropertySource注解来实现。
-
@PropertySource
注解用于指定自定义配置文件的具体位置 -
当然,如果需要将自定义配置文件中的属性值注入到对应类的属性中,可以使用
@ConfigurationProperties
或者@Value
注解进行属性值注入 -
在 resources 目录下创建 test.properties
test.id=1 test.name=张三
-
MyProperties
@Component // 自定义配置类 @PropertySource("classpath:test.properties") // 指定自定义配置文件位置和名称 @ConfigurationProperties(prefix = "test") // 指定配置文件注入属性前缀 public class MyProperties { private Integer id; private String name; // 省略属性getXX()和setXX()方法 // 省略toString()方法 }
-
MyPropertiesTest
package cn.knightzz.apply.entity; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import static org.junit.jupiter.api.Assertions.*; @RunWith(SpringRunner.class) @SpringBootTest class MyPropertiesTest { @Autowired MyProperties myProperties; @Test public void test(){ System.out.println(myProperties); } }
-
@PropertySource(“classpath:test.properties”)注解指定了自定义配置文件的位置和名称,此示例表示自定义配置文件为classpath类路径下的test.properties文件;
-
@ConfigurationProperties(prefix = “test”)注解将上述自定义配置文件test.properties中以test开头的属性值注入到该配置类属性中。