前言
本视频承接SpringBoot2基础篇以及SpringBoot2运维实用篇
SpringBoot2基础篇链接:SpringBoot2基础篇
SpringBoot2实用运维篇链接:SpringBoot2运维实用篇
本视频笔记,是根据b站黑马程序员SpringBoot视频(p67-p138
)整理而来
视频链接如下:b站黑马SpringBoot2实用开发篇
十三、热部署
13.1、手动启动热部署
笔记小结
1.开启开发者工具后启用热部署 2.使用构建项目操作启动热部署(Ctrl+F9) 3.热部署仅仅加载当前开发者自定义开发的资源,不加载jar资源
开启开发者工具
添加pom.xml依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
激活热部署:Ctrl + F9进行编译
关于热部署
重启(Restart):自定义开发代码,包含类、页面、配置文件等,加载位置restart类加载器
重载(ReLoad):jar包,加载位置base类加载器
13.2、自动启动热部署(了解)
仅做了解,不要开自动热部署
13.3、热部署范围配置
1.系统默认不触发重启的目录列表
- /META-INF/maven
- /META-INF/resources
- /resources
- /static
- /public
- /templates
2.自定义不参与重启排除项(也就是,自定义配置不参与热重启)
devtools:
restart:
exclude: public/**,static/**,config/application.yml
13.4、关闭热部署
可以在application.yml中关闭
devtools:
livereload:
enabled: false #关闭自动配置
也可以在启动类中关闭
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(SSMPApplication.class);
}
十四、配置高级
笔记小结
1.@ConfigurationProperties 2.宽松绑定/松散绑定 3.常用计量单位绑定 4.数据校验
14.1、@ConfigurationProperties*
笔记小结
@ConfigurationProperties
可以为第三方bean
绑定属性
- 使用
@ConfigurationProperties
为第三方bean绑定属性
@Component
public class TestComtroller {
@ConfigurationProperties(prefix = "datasource")
public DruidDataSource druidDataSource() {
DruidDataSource dds = new DruidDataSource();
return dds;
}
绑定第三方Bean需要通过new方法的方式
application.yml
#定义第三方bean获取
datasource:
driverClassName: com.mysql.jdbc.Driver
- 解除使用
@ConfigurationProperties
注释警告
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
14.2、@EnableConfigruationProperties
@EnableConfigurationProperties
注解可以将使用@ConfigurationProperties
注解对应的类加入Spring容器
@SpringBootApplication
@EnableConfigurationProperties(TestComtroller.class)
public class SpringBootSsmpApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSsmpApplication.class, args);
}
package com.gq.controller;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
//@Component
@ConfigurationProperties(prefix = "datasource")
public class TestComtroller {
public DruidDataSource druidDataSource() {
DruidDataSource dds = new DruidDataSource();
return dds;
}
}
注意:
@EnableConfigurationProperties
与@Component
不能同时使用。@EnableConfigurationProperties注解
,可以直接将开启的类变为@Componet
而被spring容器管理,可以少书写一个@Componet
步骤,并且同时可以开启对@ConfigurationProperties
注解的使用
补充:
14.3、宽松绑定/松散绑定
笔记小结:
1.
@ConfigurationProperties
绑定属性支持属性名宽松绑定
2.@Value
注解不支持松散绑定
3.绑定前缀命名命名规则
@ConfigurationProperties
绑定属性支持属性名宽松绑定
1.application.yml
注意:宽松绑定不支持注解@Value
引用单个属性的方式
补充:常用的方式为中划线模式
14.4、常用计量单位绑定
- JDK8支持的时间与空间计量单位
//jdk8提供的新的数据类型
//时间
@DurationUnit(ChronoUnit.HOURS)
private Duration serverTimeout;
//空间
@DataSizeUnit(DataUnit.MEGABYTES)
private DataSize dataSize;
- 常量单位坐标可点击next提示进行查看
14.5、数据校验
笔记小结
导入
JSR303
与Hibernate
校验框架坐标
使用@Validated
注解启用校验功能
使用具体校验规则规范数据校验格式
- 步骤一:添加JSR303规范坐标与Hibernate校验框架对应坐标
<!--导入JSR303规范-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<!--使用Hibernate框架提供的校验器做实现类-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
- 步骤二:开启对当前bean的属性注入校验
@Component
@Data
@ConfigurationProperties(prefix = "servers")
//开启对当前bean的属性注入校验
@Validated
public class ServerConfig {
……
}
- 步骤三:设置具体的规则
@Max(value = 8888, message = "最大值不能超过8888")
private int port;
@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;
空检查
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
Booelan检查
@AssertTrue 验证 Boolean 对象是否为 true
@AssertFalse 验证 Boolean 对象是否为 false
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length(min=, max=) string is between min and max included.
日期检查
@Past 验证 Date 和 Calendar 对象是否在当前时间之前
@Future 验证 Date 和 Calendar 对象是否在当前时间之后
@Pattern 验证 String 对象是否符合正则表达式的规则
.......等等
除此以外,我们还可以自定义一些数据校验规则
十五、测试
笔记小结
15.1、加载测试专用属性
笔记小结
加载测试临时属性应用于小范围测试环境
- 在启动测试环境时可以通过
properties
参数设置测试环境专用的属性
@SpringBootTest(properties = {"test.testporp=testValue1"})
public class PropertiesAndArgsTest {
@Value("${test.testporp}")
private String msg;
@Test
void testProperties(){
System.out.println(msg);
}
}
优势:比多环境开发中的测试环境影响范围更小,仅对当前测试类有效
- 在启动测试环境时可以通过
args
参数设置测试环境专用的传入参数
@SpringBootTest(args = {"--test.server.port=80"})
public class PropertiesAndArgsTest {
@Value("${test.arg}")
private String msg;
@Test
void testArgs(){
System.out.println(msg);
}
}
15.2、加载测试专用配置
笔记小结
加载测试范围配置应用于小范围测试环境
示例:
步骤一:添加测试bean
在test目录
下创建config/MsgConfig
类
@Configuration
public class MsgConfig {
@Bean
public String getMsg() {
return "test bean";
}
}
此时添加@Bean中仅为测试时使用,实际开发中不这样用。
步骤二:导入配置
@SpringBootTest
@Import({MsgConfig.class})
public class ConfigurationTest {
@Autowired
private String msg;
@Test
void testConfiguration() {
System.out.println(msg);
}
}
使用@Import
进行配置的导入,若导入多个配置类时,需要用逗号分隔
15.3、Web环境模拟测试
0.模拟准备
在test目录
下创建WebTEst
类
package com.gq;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebTest {
@GetMapping("/books")
public void test(){
System.out.println("springboot");
}
}
1.模拟端口
模拟web环境启动测试,启动时随机端口
//1.模拟端口
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebTest {
@Test
void testRandomPort () {
}
}
在springboot注解中添加
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT。
模拟端口中,有四种启动模式 ,RANDOM_PORT
会随机生成端口,NONE
不能启动Web服务,DEFINED_PORT
当自定义端口时则使用,同时也是默认值。
补充:若遇到测试类启动报错,留意pom.xml文件中是否添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.虚拟请求测试
模拟web环境请求测试,请求时访问/books目录
//1.模拟端口
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
//2.开启虚拟请求测试
@AutoConfigureMockMvc
public class WebTest {
@Test
//3.1注入虚拟MVC调用对象 有了此@AutoConfigureMockMvc注解,会自动注入
void testWeb(@Autowired MockMvc mvc) throws Exception {
//3.2创建虚拟请求,当前访问/books
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.get("/books");
//3.3执行请求
mvc.perform(mockHttpServletRequestBuilder);
}
}
虚拟请求测试时可在方法中注入MockMvc,并且调用MockMvcRequestBuilders.get方法获取请求的路径,再有MockMvc来执行调用
虚拟请求状态匹配
@Test
//3.1注入虚拟MVC调用对象
void testStatus(@Autowired MockMvc mvc) throws Exception {
//3.2创建虚拟请求,当前访问/books
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.get("/books");
//3.3执行请求
ResultActions actions = mvc.perform(mockHttpServletRequestBuilder);
//3.4匹配执行状态(是否预期值)
//3.4.1定义执行状态匹配器
StatusResultMatchers status = MockMvcResultMatchers.status();
//3.4.2定义预期执行状态
ResultMatcher ok = status.isOk();
//3.5.3使用本次真实执行结果与预期结果进行比对
actions.andExpect(ok);
}
虚拟请求响应体匹配
@Test
//3.1注入虚拟MVC调用对象
void testBody(@Autowired MockMvc mvc) throws Exception {
//3.2创建虚拟请求,当前访问/books
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.get("/books");
//3.3执行请求
ResultActions actions = mvc.perform(mockHttpServletRequestBuilder);
//3.4匹配执行状态(是否预期值)
//3.4.1定义执行状态匹配器
ContentResultMatchers content = MockMvcResultMatchers.content();
//3.4.2定义预期执行状态
ResultMatcher result = content.string("springboot");
//3.5.3使用本次真实执行结果与预期结果进行比对
actions.andExpect(result);
}
虚拟请求响应体(json)匹配
@Test
//3.1注入虚拟MVC调用对象
void testJson(@Autowired MockMvc mvc) throws Exception {
//3.2创建虚拟请求,当前访问/books
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.get("/books");
//3.3执行请求
ResultActions actions = mvc.perform(mockHttpServletRequestBuilder);
//3.4匹配执行状态(是否预期值)
//3.4.1定义执行状态匹配器
ContentResultMatchers content = MockMvcResultMatchers.content();
//3.4.2定义预期执行状态
ResultMatcher result = content.json("{\"id\":1,\"type\":\"美女\",\"name\":\"玥玥\",\"description\":\"大美女只为你着迷\"}");
//3.5.3使用本次真实执行结果与预期结果进行比对
actions.andExpect(result);
}
虚拟请求响应头匹配
@Test
//3.1注入虚拟MVC调用对象
void testHead(@Autowired MockMvc mvc) throws Exception {
//3.2创建虚拟请求,当前访问/books
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.get("/books");
//3.3执行请求
ResultActions actions = mvc.perform(mockHttpServletRequestBuilder);
//3.4匹配执行状态(是否预期值)
//3.4.1定义执行状态匹配器
HeaderResultMatchers header = MockMvcResultMatchers.header();
//3.4.2定义预期执行状态
ResultMatcher contentType = header.string("Content-Type", "application/json");
//3.5.3使用本次真实执行结果与预期结果进行比对
actions.andExpect(contentType);
}
示例:
一般情况下响应的测试
@Test
void testGetById(@Autowired MockMvc mvc) throws Exception {
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
ResultActions actions = mvc.perform(builder);
//测试响应状态
StatusResultMatchers status = MockMvcResultMatchers.status();
ResultMatcher ok = status.isOk();
actions.andExpect(ok);
//测试响应头
HeaderResultMatchers header = MockMvcResultMatchers.header();
ResultMatcher string = header.string("Content-Type", "application/json");
actions.andExpect(string);
//测试响应体
ContentResultMatchers content = MockMvcResultMatchers.content();
ResultMatcher json = content.json("{\"id\":1,\"type\":\"美女\",\"name\":\"玥玥\",\"description\":\"大美女只为你着迷\"}");
actions.andExpect(json);
}
15.4、业务层测试回滚
目的:测试类里面的所有操作(例如对数据库得增删改查),只想看到效果,不想真正把数据库改了
解决方法:给测试类添加一个事务,事物设置为回滚
为测试用例添加事务,SpringBoot会对测试用例对应的事务提交操作进行回滚
@SpringBootTest
@Transactional
public class DaoTest {
}
如果想在测试用例中提交事务,可以通过
@Rollback
注解设置
@SpringBootTest
@Transactional
@Rollback(false)
public class DaoTest {
}
示例:
/*
* 测试业务层的方法时需要开启@Transactional注解并与@Rollback(value = true)连用,可以进行测试数据的回滚操作。(换句话说,也就是数据库不会自动新增消息)
* */
@SpringBootTest
@Transactional
@Rollback(value = true)
public class DaoTest {
@Autowired
private IBookService service;
@Test
void testSave() {
Book book = new Book();
book.setType("meinv fd ");
book.setName("yueyue");
book.setDescription("dameinvzhiweinizhaomi");
service.saveBook(book);
}
}
15.5、测试用例数据设定
测试用例数据通常采用随机值进行测试,使用SpringBoot提供的随机数为其赋值
在application.yml
文件下
testcase:
book:
id: ${random.int} # 随机整数
id2: ${random.int(10)} # 10以内随机数
type: ${random.int(10,20)} # 10到20随机数
uuid: ${random.uuid} # 随机uuid
name: ${random.value} # 随机字符串,MD5字符串,32位
publishTime: ${random.long} # 随机整数(long范围)
示例:
在test的testCase/domain下创建BookCase
@Component
@Data
@ConfigurationProperties(prefix = "testcase.book")
public class BookCase {
private int id;
private int id2;
private int type;
private String uuid;
private String name;
private long publishTime;
}
在test下创建testCaseTest
@SpringBootTest
public class testCaseTest {
@Autowired
private BookCase bookCase;
@Test
void testCase() {
System.out.println(bookCase);
}
}
十六、数据层解决方案
现有数据层解决方案技术选型
Druid + MyBatis-Plus + MySQL
- 数据源:DruidDataSource
- 持久化技术:MyBatis-Plus / MyBatis
- 数据库:MySQL
16.1、SQL
16.1.1、数据源配置
笔记小结
1.SpringBoot内置3款数据源可供选择 HikariCP(默认),如果自己不配置数据源,那么springboot自动用Hikari Tomcat提供DataSource Commons DBCP
格式一:标准格式
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: qweasdzxc
格式二:使用type
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: qweasdzxc
type: com.alibaba.druid.pool.DruidDataSource
SpringBoot提供了3种内嵌的数据源对象供开发者选择
- HikariCP:默认内置数据源对象
- Tomcat提供DataSource:HikariCP不可用的情况下,且在web环境中,将使用tomcat服务器配置的数据源对象
- Commons DBCP:Hikari不可用,tomcat数据源也不可用,将使用dbcp数据源
通用配置无法设置具体的数据源配置信息,仅提供基本的连接相关配置,如需配置,在下一级配置中设置具体设定
#hikari数据源
spring:
datasource:
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: qweasdzxc
#最大连接池
hikari:
maximum-pool-size: 50
16.1.2、持久化技术配置
(SpringBoot默认的是JDBCTemplate 但是这个太麻烦,太老了 不用这个)
16.1.3、数据库配置
SpringBoot提供了3种内嵌数据库供开发者选择,提高开发测试效率
- H2(默认)
- HSQL
- Derby
不使用这个,实际中使用Mysql