尚硅谷spring boot 2核心技术学习笔记

发布时间:2022-12-24 14:30

开发前先查看系统Java和maven的版本
尚硅谷spring boot 2核心技术学习笔记_第1张图片

参考资料

1、尚硅谷/SpringBoot2核心技术与响应式编程
2、springboot官网
尚硅谷spring boot 2核心技术学习笔记_第2张图片
3、版本升级变化
尚硅谷spring boot 2核心技术学习笔记_第3张图片

maven环境配置

尚硅谷spring boot 2核心技术学习笔记_第4张图片

<mirrors>
      <mirror>
        <id>nexus-aliyunid>
        <mirrorOf>centralmirrorOf>
        <name>Nexus aliyunname>
        <url>http://maven.aliyun.com/nexus/content/groups/publicurl>
      mirror>
  mirrors>
 
  <profiles>
         <profile>
              <id>jdk-1.8id>
              <activation>
                <activeByDefault>trueactiveByDefault>
                <jdk>1.8jdk>
              activation>
              <properties>
                <maven.compiler.source>1.8maven.compiler.source>
                <maven.compiler.target>1.8maven.compiler.target>
                <maven.compiler.compilerVersion>1.8maven.compiler.compilerVersion>
              properties>
         profile>
  profiles>

一、spring boot helloworld

参考官网
尚硅谷spring boot 2核心技术学习笔记_第5张图片

1.1、创建项目

new maven项目
尚硅谷spring boot 2核心技术学习笔记_第6张图片

1.2、pom.xml


<parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>2.6.3version>
parent>

<dependencies>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
dependencies>

1.3、工程结构和主程序类

尚硅谷spring boot 2核心技术学习笔记_第7张图片

1.4、Controller

尚硅谷spring boot 2核心技术学习笔记_第8张图片

1.5、运行结果

尚硅谷spring boot 2核心技术学习笔记_第9张图片

二、spring boot通用配置(基于一spring boot helloworld)

https://docs.spring.io/spring-boot/docs/current/reference/html/
尚硅谷spring boot 2核心技术学习笔记_第10张图片
服务器配置
尚硅谷spring boot 2核心技术学习笔记_第11张图片这里通过简单使用配置文件,修改tomcat的端口
尚硅谷spring boot 2核心技术学习笔记_第12张图片
尚硅谷spring boot 2核心技术学习笔记_第13张图片

三、spring boot简化部署(基于一spring boot helloworld)

创建可执行 Jar
尚硅谷spring boot 2核心技术学习笔记_第14张图片
在pom.xml的dependencies部分下方添加打包插件

 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
            
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-resources-pluginartifactId>
                <version>3.1.0version>
            plugin>
        plugins>
    build>

使用maven进行项目的打包
尚硅谷spring boot 2核心技术学习笔记_第15张图片
生成jar包
尚硅谷spring boot 2核心技术学习笔记_第16张图片
使用命令行代替服务器启动项目
尚硅谷spring boot 2核心技术学习笔记_第17张图片

一样可以访问:说明这打包时将tomcat等环境一起打包成jar包了,这样这服务器就可以不用安装tomcat等工具,节约成本
尚硅谷spring boot 2核心技术学习笔记_第18张图片

四、了解自动配置原理(基于一spring boot helloworld)

4.1、SpringBoot特点

4.1.1、依赖管理和版本仲裁

父项目做依赖管理
尚硅谷spring boot 2核心技术学习笔记_第19张图片
1、自定义版本,替换spring boot引入的默认版本
查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
尚硅谷spring boot 2核心技术学习笔记_第20张图片
在当前项目里面重写配置,这样就导进来自己安装的数据库版本
在这里插入图片描述

4.1.2、starter场景启动器

2、开发导入starter场景启动器
官方文档:https://docs.spring.io/spring-boot/docs/current/reference/html/
尚硅谷spring boot 2核心技术学习笔记_第21张图片
尚硅谷spring boot 2核心技术学习笔记_第22张图片

1、见到很多 spring-boot-starter-* : *就某种场景
2、只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
3、SpringBoot所有支持的场景
https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters
4、见到的  *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
5、所有场景启动器最底层的依赖
<dependency>
  <groupId>org.springframework.bootgroupId>
  <artifactId>spring-boot-starterartifactId>
  <version>2.3.4.RELEASEversion>
  <scope>compilescope>
dependency>

4.2、自动配置

1、● 自动配好Tomcat
○ 引入Tomcat依赖。
○ 配置Tomcat(默认自动配置)

2、● 自动配好SpringMVC
○ 引入SpringMVC全套组件
○ 自动配好SpringMVC常用组件(功能)

4.2.1、查看引入的组件

尚硅谷spring boot 2核心技术学习笔记_第23张图片
3、● 自动配好Web常见功能,如:字符编码问题
○ SpringBoot帮我们配置好了所有web开发的常见场景

4、● 默认的包结构
○ 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
○ 无需以前的包扫描配置
○ 想要改变扫描路径,@SpringBootApplication(scanBasePackages=“com.atguigu”)
或者@ComponentScan 指定扫描路径尚硅谷spring boot 2核心技术学习笔记_第24张图片
//@SpringBootApplication //等同下面的三个注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(“com.atguigu.boot”)//指定包扫描的基包

5、● 各种配置拥有默认值
○ 默认配置最终都是映射到某个类上,如:MultipartProperties
○ 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象

6、● 按需加载所有自动配置项
○ 非常多的starter
○ 引入了哪些场景这个场景的自动配置才会开启
○ SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

4.3、容器功能

尚硅谷spring boot 2核心技术学习笔记_第25张图片

4.3.1、注册组件两种方式

一、使用@Configuration和@Bean注解方式
二、给容器导入组件@Import
1、 基本使用
MyConfig.java

/**
 * @Configuration:告诉SpringBoot这是一个配置类 == 配置文件
 * proxyBeanMethods:表示代理bean的方法
 *      Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *      Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 * 组件依赖必须使用Full模式默认。其他默认是否Lite模式
 */
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = true)
public class MyConfig {
    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        //因为proxyBeanMethods = true,所以user组件依赖了Pet组件,单实例
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }

    @Bean("tom")//使用参数自定义组件id
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

MainApplication.java

/*
 * 主程序类:所有程序的启动入口
 * @SpringBootApplication作用:这是一个springboot运用
 */
//@SpringBootApplication //等同下面的三个注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")//指定包扫描的基包
public class MainApplication {
    /*===========main方法===========*/
    public static void main(String[] args) {

        //1、返回我们IOC容器,里面包含各种组件
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2、查看容器里面的所有组件
//        String[] names = run.getBeanDefinitionNames();
//        System.out.println("================");
//        for (String name : names) {
//            System.out.println(name);
//        }

        //3、从容器中获取组件,验证是否单实例组件
        Pet tom01 = run.getBean("tom", Pet.class);
        Pet tom02 = run.getBean("tom", Pet.class);
        System.out.println("是否单实例组件:" + (tom01 == tom02));
        System.out.println("================");

        //4、配置类本身也是一个组件
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println("配置类本身也是一个组件:"+bean);
        System.out.println("================");

        //5、如果@Configuration(proxyBeanMethods = true)代理对象调用方法。
        //SpringBoot总会检查这个组件是否在容器中有保持组件单实例
        User user = bean.user01();
        User user1 = bean.user01();
        System.out.println("user == user1:" + (user == user1));
        System.out.println("================");

        //6、组件依赖
        User user01 = run.getBean("user01", User.class);
        Pet tom = run.getBean("tom", Pet.class);
        System.out.println("用户的宠物:"+(user01.getPet() == tom));

        //使用@Import导入自定义和外部组件测试
        String[] beanNamesForType = run.getBeanNamesForType(User.class);
        System.out.println("======获取组件");
        for (String s : beanNamesForType) {
            System.out.println(s);
        }

        DBHelper dbHelperBean = run.getBean(DBHelper.class);
        System.out.println("dbHelperBean"+dbHelperBean);
    }
}

尚硅谷spring boot 2核心技术学习笔记_第26张图片

4.3.2、条件装配@Conditional

条件装配:满足Conditional指定的条件,则进行组件注入
尚硅谷spring boot 2核心技术学习笔记_第27张图片

@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(name = "tom")//也可以注解在类上,表示容器中存在tom组件时,才加载这个类里面的组件
public class MyConfig {
    //@ConditionalOnBean(name = "tom")//容器中存在tom组件时才加载user01组件,
    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        //因为proxyBeanMethods = true,所以user组件依赖了Pet组件,单实例
        //zhangsan.setPet(tomcatPet());
        return zhangsan;
    }

    @Bean("tom22")//使用参数自定义组件id
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

4.3.3、原生配置文件引入@ImportResource

解决问题:一些公司还是使用xml文件配置方式,所以需要将这些文件引进来,进行解析配置
尚硅谷spring boot 2核心技术学习笔记_第28张图片

尚硅谷spring boot 2核心技术学习笔记_第29张图片

MainApplication.java

/*
 * 主程序类:所有程序的启动入口
 * @SpringBootApplication作用:这是一个springboot运用
 */
//@SpringBootApplication //等同下面的三个注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")//指定包扫描的基包
public class MainApplication {
    /*===========main方法===========*/
    public static void main(String[] args) {

        //1、返回我们IOC容器,里面包含各种组件
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2、查看容器里面的所有组件
//        String[] names = run.getBeanDefinitionNames();
//        System.out.println("================");
//        for (String name : names) {
//            System.out.println(name);
//        }

        //3、从容器中获取组件,验证是否单实例组件
//        Pet tom01 = run.getBean("tom", Pet.class);
//        Pet tom02 = run.getBean("tom", Pet.class);
//        System.out.println("是否单实例组件:" + (tom01 == tom02));
//        System.out.println("================");
//
//        //4、配置类本身也是一个组件
//        MyConfig bean = run.getBean(MyConfig.class);
//        System.out.println("配置类本身也是一个组件:"+bean);
//        System.out.println("================");
//
//        //5、如果@Configuration(proxyBeanMethods = true)代理对象调用方法。
//        //SpringBoot总会检查这个组件是否在容器中有保持组件单实例
//        User user = bean.user01();
//        User user1 = bean.user01();
//        System.out.println("user == user1:" + (user == user1));
//        System.out.println("================");
//
//        //6、组件依赖
//        User user01 = run.getBean("user01", User.class);
//        Pet tom = run.getBean("tom", Pet.class);
//        System.out.println("用户的宠物:"+(user01.getPet() == tom));
//
//        //使用@Import导入自定义和外部组件测试
//        String[] beanNamesForType = run.getBeanNamesForType(User.class);
//        System.out.println("======获取组件");
//        for (String s : beanNamesForType) {
//            System.out.println(s);
//        }
//
//        DBHelper dbHelperBean = run.getBean(DBHelper.class);
//        System.out.println("dbHelperBean"+dbHelperBean);

        //原生配置文件引入@ImportResource测试
        boolean haha = run.containsBean("haha");
        boolean hehe = run.containsBean("hehe");
        System.out.println("haha:"+haha);//true
        System.out.println("hehe:"+hehe);//true
    }
}

4.3.4、配置绑定的properties文件的2种方式

一、方式一,在bean上配置

使用
@Component
@ConfigurationProperties(prefix = “mycar”)

properties配置文件
尚硅谷spring boot 2核心技术学习笔记_第30张图片
接收解析properties配置文件的bean
尚硅谷spring boot 2核心技术学习笔记_第31张图片
尚硅谷spring boot 2核心技术学习笔记_第32张图片
尚硅谷spring boot 2核心技术学习笔记_第33张图片

二、方式二,在配置类,和bean上同时配置

@ConfigurationProperties(prefix = “mycar”)
public class Car {

@EnableConfigurationProperties(Car.class)
public class MyConfig {

bean文件
尚硅谷spring boot 2核心技术学习笔记_第34张图片
配置类文件
尚硅谷spring boot 2核心技术学习笔记_第35张图片
尚硅谷spring boot 2核心技术学习笔记_第36张图片

4.4、最佳实践

1、● 引入场景依赖
○ https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters
2、● 查看自动配置了哪些(选做)
○ 自己分析,引入场景对应的自动配置一般都生效了
○ 配置文件中debug=true开启自动配置报告。控制台打印的Negative(不生效)、Positive(生效),如下:
尚硅谷spring boot 2核心技术学习笔记_第37张图片尚硅谷spring boot 2核心技术学习笔记_第38张图片
3、● 是否需要修改
○ 参照文档修改配置项
■ https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties
■ 自己分析。xxxxProperties绑定了配置文件的哪些。
实例:修改banner图
尚硅谷spring boot 2核心技术学习笔记_第39张图片

4、 ○ 自定义加入或者替换组件
■ @Bean、@Component…
○ 自定义器 XXXXXCustomizer;
○ …

五、开发小技巧

5.1、Lombok,简化JavaBean开发

作用:简化JavaBean开发
使用@Data注解,不用再写get、set方法
使用@ToString注解,不用再写tostring方法。
使用@NoArgsConstructor注解,不用再写无参构造方法。
使用@AllArgsConstructor注解,不用再写有参构造方法。

步骤一:引入依赖


<dependency>
	 <groupId>org.projectlombokgroupId>
	 <artifactId>lombokartifactId>
dependency>

步骤二:安装插件
file->settting->plugin
尚硅谷spring boot 2核心技术学习笔记_第40张图片
步骤三:
使用注解实现简化JavaBean开发
尚硅谷spring boot 2核心技术学习笔记_第41张图片

5.2、日志使用

尚硅谷spring boot 2核心技术学习笔记_第42张图片

5.3、dev-tools,热部署自动重启,加快项目的启动


<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-devtoolsartifactId>
	<optional>trueoptional>
dependency>

使用
Ctrl+F9即可重新编译加载,并启动项目

5.4、spring Initailizr(项目初始化向导)

尚硅谷spring boot 2核心技术学习笔记_第43张图片
尚硅谷spring boot 2核心技术学习笔记_第44张图片
引入场景依赖和选择springboot版本
尚硅谷spring boot 2核心技术学习笔记_第45张图片
删除多余的文件
尚硅谷spring boot 2核心技术学习笔记_第46张图片
项目展开
尚硅谷spring boot 2核心技术学习笔记_第47张图片

六、SpringBoot2核心技术-核心功能

尚硅谷spring boot 2核心技术学习笔记_第48张图片

6.1、文件类型

6.1.1、properties

同以前的properties用法

6.1.2、yaml

一、简介
YAML 是 “YAML Ain’t Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。 适合用来做以数据为中心的配置文件

二、基本语法
● key: value;kv之间有空格
● 大小写敏感
● 使用缩进表示层级关系
● 缩进不允许使用tab,只允许空格
● 缩进的空格数不重要,只要相同层级的元素左对齐即可
● '#'表示注释
● 字符串无需加引号,如果要加,单引号会将/n作为字符串输出,双引号会将/n转译成换行输出

三、数据类型
1、字面量:单个的、不可再分的值。date、boolean、string、number、null

k: v

2、对象:键值对的集合。map、hash、set、object

行内写法:  k: {k1:v1,k2:v2,k3:v3}
#或
k: 
  k1: v1
  k2: v2
  k3: v3

3、数组:一组按次序排列的值。array、list、queue

行内写法:  k: [v1,v2,v3]
#或者
k:
 - v1
 - v2
 - v3

== 实例 ==

person:
  # 字面量:单个的、不可再分的值。date、boolean、string、number、null
  userName: 'zhangsan \n 王二毛'  # 单引号会将\n作为字符串输出,双引号会将\n作为换行输出
  boss: false
  birth: 2019/12/12 20:12:33
  age: 18
  pet:
    name: tomcat
    weight: 23.4
  # 数组:一组按次序排列的值。array、list、queue
  interests: [篮球,游泳]
  animal:
    - jerry
    - mario
  # 对象:键值对的集合。map、hash、set、object ,下面展示三种写法
  score:
    english:
      first: 30
      second: 40
      third: 50
    math: [131,140,148]
    chinese: {first: 128,second: 136}
  salarys: [3999,4999.98,5999.99]

  allPets:
    sick: # 字面量
      - {name: tom} # 数组list
      - {name: jerry,weight: 47}
    health: [{name: mario,weight: 47}]

尚硅谷spring boot 2核心技术学习笔记_第49张图片
尚硅谷spring boot 2核心技术学习笔记_第50张图片

6.1.3、配置注释处理器 ,yaml编写提示

这样在编写yaml文件时就会有提示信息,可以快速准确开发


<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-configuration-processorartifactId>
	<optional>trueoptional>
dependency>

尚硅谷spring boot 2核心技术学习笔记_第51张图片
配置注释处理器只是为了开发方便,所以在打包的时候就不要将该工具添加到包中,因此需要进行一下配置

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombokgroupId>
                            <artifactId>lombokartifactId>
                        exclude>
                        
                        <exclude>
                            <groupId>org.springframework.bootgroupId>
                            <artifactId>spring-boot-configuration-processorartifactId>
                        exclude>
                    excludes>
                configuration>
            plugin>
        plugins>
    build>

6.2、Web开发

尚硅谷spring boot 2核心技术学习笔记_第52张图片
创建工程
尚硅谷spring boot 2核心技术学习笔记_第53张图片

6.2.1、静态资源访问

1、静态资源目录
只要静态资源放在类路径下: /static or /public or /resources or /META-INF/resources
访问方式: 当前项目根路径/ + 静态资源名
例如:http://localhost:8080/earth.png

原理:静态映射/**。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
尚硅谷spring boot 2核心技术学习笔记_第54张图片
2、改变默认的静态资源访问路径
访问方式:http://localhost:8080/res/earth.png,就是在静态资源前加多一个前缀res
尚硅谷spring boot 2核心技术学习笔记_第55张图片

3、改变默认的静态资源的存放位置

spring:
  mvc:
    static-path-pattern: /res/** #当前项目下的res/访问路径访问的都是静态资源

  #改变默认的静态资源的存放位置
  web:
    resources:
      static-locations: [classpath:/haha/]

尚硅谷spring boot 2核心技术学习笔记_第56张图片
访问地址:
http://localhost:8080/res/public/1.jpg
http://localhost:8080/res/resources/earth.png

6.2.2、webjars的使用:引入jQuery,bootstrap等的jar包

<dependency>
    <groupId>org.webjars.npmgroupId>
    <artifactId>jqueryartifactId>
    <version>3.6.0version>
dependency>

尚硅谷spring boot 2核心技术学习笔记_第57张图片

访问地址:http://localhost:8080/webjars/jquery/3.6.0/src/jquery.js 后面地址要按照依赖里面的包路径

6.2.3、欢迎页

● 方式一:直接在静态资源路径下 添加index.html
注意:
○ 可以配置静态资源路径
○ 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问

spring:
#  mvc:
#    static-path-pattern: /res/** #当前项目下的res/访问路径访问的都是静态资源

  #改变默认的静态资源的存放位置
  web:
    resources:
      static-locations: [classpath:/haha/]

访问根路径即可来到欢迎页
在这里插入图片描述

● 方式二:controller能处理/index

6.2.4、自定义 Favicon

favicon.ico 放在静态资源目录下即可。
尚硅谷spring boot 2核心技术学习笔记_第58张图片

但是,下面这些要关闭

#spring:
#  mvc:
#    static-path-pattern: /res/** #当前项目下的res/访问路径访问的都是静态资源

  #改变默认的静态资源的存放位置
#  web:
#    resources:
#      static-locations: [classpath:/haha/]

尚硅谷spring boot 2核心技术学习笔记_第59张图片

6.2.5、请求映射——rest使用与原理

Rest原理(表单提交要使用REST的时候)
开启映射,默认是关闭的
尚硅谷spring boot 2核心技术学习笔记_第60张图片
尚硅谷spring boot 2核心技术学习笔记_第61张图片
Controller

@RestController
public class HelloController {

    @RequestMapping("/earth.png")
    public String hello() {
        return "aaaa";
    }

    @GetMapping("/user")
    public String getUser(){
        return "GET-张三";
    }

    @PostMapping("/user")
    public String saveUser(){
        return "POST-张三";
    }

    @PutMapping("/user")
    public String putUser(){
        return "PUT-张三";
    }

    @DeleteMapping("/user")
    public String deleteUser(){
        return "DELETE-张三";
    }

//    扩展点:如何把 _method 这个名字换成我们自己喜欢的
}

尚硅谷spring boot 2核心技术学习笔记_第62张图片

尚硅谷spring boot 2核心技术学习笔记_第63张图片
基于上面的程序,解决扩展点:如何把 _method 这个名字换成我们自己喜欢的
尚硅谷spring boot 2核心技术学习笔记_第64张图片
尚硅谷spring boot 2核心技术学习笔记_第65张图片

6.2.6、普通参数与基本注解

1、注解:
@PathVariable 获取请求路径中占位符的值例如:@PathVariable(“id”) Integer id
@RequestHeader
@RequestParam
@CookieValue
@RequestBody
@MatrixVariable 处理矩阵变量
@ModelAttribute
尚硅谷spring boot 2核心技术学习笔记_第66张图片

//  car/3/owner/lisi
    @GetMapping("/car/{id}/owner/{username}")
    public Map<String,Object> getCar(//获取请求路径中占位符的值
                                     @PathVariable("id") Integer id,
                                     @PathVariable("username") String name,
                                     @PathVariable Map<String,String> pv,//将请求路径中占位符都封装到Map中
                                     //获取请求头信息
                                     @RequestHeader("User-Agent") String userAgent,//获取指定请求头信息
                                     @RequestHeader Map<String,String> header,//获取所有请求头信息
                                     //获取请求参数的值
                                     @RequestParam("age") Integer age,
                                     @RequestParam("inters") List<String> inters,
                                     @RequestParam Map<String,String> params,
                                     //获取Cookie的值
                                     @CookieValue("originURI") String originURI,
                                     @CookieValue("originURI") Cookie cookie
                                     ){
        Map<String,Object> map = new HashMap<>();

//        map.put("id",id);
//        map.put("name",name);
//        map.put("pv",pv);
//        map.put("userAgent",userAgent);
//        map.put("headers",header);
        map.put("age",age);
        map.put("inters",inters);
        map.put("params",params);
        map.put("originURI",originURI);
        System.out.println(cookie.getName()+"===>"+cookie.getValue());
        return map;
    }
}

尚硅谷spring boot 2核心技术学习笔记_第67张图片
@RequestBody 的使用实例
post请求才有请求体
尚硅谷spring boot 2核心技术学习笔记_第68张图片

 @PostMapping("/save")
    public Map postMethod(@RequestBody String content){
        Map<String,Object> map = new HashMap<>();
        map.put("content",content);
        return map;
    }

尚硅谷spring boot 2核心技术学习笔记_第69张图片
@MatrixVariable 处理矩阵变量的实例(比较复杂)
尚硅谷spring boot 2核心技术学习笔记_第70张图片

尚硅谷spring boot 2核心技术学习笔记_第71张图片
尚硅谷spring boot 2核心技术学习笔记_第72张图片
尚硅谷spring boot 2核心技术学习笔记_第73张图片
尚硅谷spring boot 2核心技术学习笔记_第74张图片

2、Servlet API:
WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId
在这里插入图片描述

3、复杂参数:
Map、Model(map、model里面的数据会被放在request的请求域 request.setAttribute)、Errors/BindingResult、RedirectAttributes( 重定向携带数据)、ServletResponse(response)、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder
Map map, Model model, HttpServletRequest request 都是可以给request域中放数据,
request.getAttribute();
尚硅谷spring boot 2核心技术学习笔记_第75张图片
尚硅谷spring boot 2核心技术学习笔记_第76张图片

尚硅谷spring boot 2核心技术学习笔记_第77张图片

4、自定义对象参数POJO:
可以自动类型转换与格式化,可以级联封装。
尚硅谷spring boot 2核心技术学习笔记_第78张图片
尚硅谷spring boot 2核心技术学习笔记_第79张图片

尚硅谷spring boot 2核心技术学习笔记_第80张图片
尚硅谷spring boot 2核心技术学习笔记_第81张图片
使用格式化器,自定义Converter,实现级联封装
尚硅谷spring boot 2核心技术学习笔记_第82张图片
尚硅谷spring boot 2核心技术学习笔记_第83张图片
在这里插入图片描述

6.2.7、数据响应与内容协商——返回json或xml

SpringMVC到底支持哪些返回值

ModelAndView
Model
View
ResponseEntity 
ResponseBodyEmitter
StreamingResponseBody
HttpEntity
HttpHeaders
Callable
DeferredResult
ListenableFuture
CompletionStage
WebAsyncTask
有 @ModelAttribute 且为对象类型的
@ResponseBody 注解 ---> RequestResponseBodyMethodProcessor;

1、内容协商
根据客户端接收能力不同,返回不同媒体类型的数据。
引入xml依赖

 <dependency>
     <groupId>com.fasterxml.jackson.dataformatgroupId>
     <artifactId>jackson-dataformat-xmlartifactId>
dependency>

基于请求头的内容协商策略:
(获取客户端Accept请求头字段)【application/xml】则服务端响应xml格式数据
【application/json】则服务端响应json格式数据

开启基于浏览器参数方式内容协商功能
为了方便内容协商,开启基于请求参数的内容协商功能。

spring:
    contentnegotiation:
      favor-parameter: true  #开启请求参数内容协商模式

发请求: http://localhost:8080/test/person?format=json
http://localhost:8080/test/person?format=xml

自定义 MessageConverter
实现多协议数据兼容。json、xml、x-guigu
0、@ResponseBody 响应数据出去 调用 RequestResponseBodyMethodProcessor 处理
1、Processor 处理方法返回值。通过 MessageConverter 处理
2、所有 MessageConverter 合起来可以支持各种媒体类型数据的操作(读、写)
3、内容协商找到最终的 messageConverter;

SpringMVC的什么功能。一个入口给容器中添加一个 WebMvcConfigurer
尚硅谷spring boot 2核心技术学习笔记_第84张图片
尚硅谷spring boot 2核心技术学习笔记_第85张图片
在这里插入图片描述

6.2.8、模板引擎-Thymeleaf(视图解析和模板引擎)

现代化、服务端Java模板引擎
一、基本语法

1、表达式
表达式名字	语法				用途
变量取值		${...} 		获取请求域、session域、对象等值
选择变量		*{...}		获取上下文对象值
消息		#{...}		获取国际化等值
链接		@{...}		生成链接
片段表达式	~{...}		jsp:include 作用,引入公共页面片段

2、字面量
文本值: 'one text' , 'Another one!' ,…数字: 0 , 34 , 3.0 , 12.3 ,…布尔值: true , false
空值: null
变量: one,two,.... 变量不能有空格
3、文本操作
字符串拼接: +
变量替换: |The name is ${name}| 

4、数学运算
运算符: + , - , * , / , %

5、布尔运算
运算符:  and , or
一元运算: ! , not 


6、比较运算
比较: > , < , >= , <= ( gt , lt , ge , le )等式: == , != ( eq , ne ) 

7、条件运算
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue) 

8、特殊操作
无操作: _

二、设置属性值-th:attr

设置单个值
<form action="subscribe.html" th:attr="action=@{/subscribe}">
  <fieldset>
    <input type="text" name="email" />
    <input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/>
  fieldset>
form>
设置多个值
<img src="../../images/gtvglogo.png"  th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
以上两个的代替写法 th:xxxx
<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>
<form action="subscribe.html" th:action="@{/subscribe}">

三、迭代

<tr th:each="prod : ${prods}">
        <td th:text="${prod.name}">Onionstd>
        <td th:text="${prod.price}">2.41td>
        <td th:text="${prod.inStock}? #{true} : #{false}">yestd>
tr>

<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
  <td th:text="${prod.name}">Onionstd>
  <td th:text="${prod.price}">2.41td>
  <td th:text="${prod.inStock}? #{true} : #{false}">yestd>
tr>

四、条件运算

<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:if="${not #lists.isEmpty(prod.comments)}">viewa>

<div th:switch="${user.role}">
  <p th:case="'admin'">User is an administratorp>
  <p th:case="#{roles.manager}">User is a managerp>
  <p th:case="*">User is some other thingp>
div>

6.2.8.1、tymeleaf使用

1、引入tarter

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-thymeleafartifactId>
dependency>

尚硅谷spring boot 2核心技术学习笔记_第86张图片
尚硅谷spring boot 2核心技术学习笔记_第87张图片

七、构建后台管理系统

7.1、Thymeleaf使用

尚硅谷spring boot 2核心技术学习笔记_第88张图片
尚硅谷spring boot 2核心技术学习笔记_第89张图片
表格数据的提交
尚硅谷spring boot 2核心技术学习笔记_第90张图片
修改标签属性,接受表格数据,显示在前端页面
在这里插入图片描述
遍历数据显示数据在前端页面
尚硅谷spring boot 2核心技术学习笔记_第91张图片
内容的引用和替换
官方例子说明
尚硅谷spring boot 2核心技术学习笔记_第92张图片
实例
尚硅谷spring boot 2核心技术学习笔记_第93张图片
尚硅谷spring boot 2核心技术学习笔记_第94张图片

7.2、拦截器检查

尚硅谷spring boot 2核心技术学习笔记_第95张图片
尚硅谷spring boot 2核心技术学习笔记_第96张图片
尚硅谷spring boot 2核心技术学习笔记_第97张图片

7.3、文件上传功能开发

尚硅谷spring boot 2核心技术学习笔记_第98张图片
尚硅谷spring boot 2核心技术学习笔记_第99张图片
尚硅谷spring boot 2核心技术学习笔记_第100张图片
尚硅谷spring boot 2核心技术学习笔记_第101张图片

7.4、错误处理

7.4.1、定制处理逻辑

1、● 自定义错误页
○ error/404.html error/5xx.html;有精确的错误状态码页面就匹配精确,没有就找 4xx.html;如果都没有就触发白页
尚硅谷spring boot 2核心技术学习笔记_第102张图片
尚硅谷spring boot 2核心技术学习笔记_第103张图片

2、@ControllerAdvice+@ExceptionHandler处理全局异常;底层是 ExceptionHandlerExceptionResolver 支持的
尚硅谷spring boot 2核心技术学习笔记_第104张图片
尚硅谷spring boot 2核心技术学习笔记_第105张图片
下面是数学异常处理结果
尚硅谷spring boot 2核心技术学习笔记_第106张图片
3、@ResponseStatus+自定义异常 ;底层是 ResponseStatusExceptionResolver ,把responsestatus注解的信息底层调用 response.sendError(statusCode, resolvedReason);tomcat发送的/error
尚硅谷spring boot 2核心技术学习笔记_第107张图片
尚硅谷spring boot 2核心技术学习笔记_第108张图片
尚硅谷spring boot 2核心技术学习笔记_第109张图片
4、● Spring底层的异常,如 参数类型转换异常;DefaultHandlerExceptionResolver 处理框架底层的异常。
○ response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());

5、自定义实现 HandlerExceptionResolver 处理异常;可以作为默认的全局异常处理规则
尚硅谷spring boot 2核心技术学习笔记_第110张图片
尚硅谷spring boot 2核心技术学习笔记_第111张图片

6、● ErrorViewResolver 实现自定义处理异常;
○ response.sendError 。error请求就会转给controller
○ 你的异常没有任何人能处理。tomcat底层 response.sendError。error请求就会转给controller
○ basicErrorController 要去的页面地址是 ErrorViewResolver ;

7.5、Web原生组件注入(Servlet、Filter、Listener)

7.5.1、使用Servlet API(推荐使用)

@ServletComponentScan(basePackages = “com.atguigu.admin”) :指定原生Servlet组件都放在那里
@WebServlet(urlPatterns = “/my”):效果:直接响应,没有经过Spring的拦截器?
@WebFilter(urlPatterns={"/css/","/images/"})
@WebListener
1、Servlet
尚硅谷spring boot 2核心技术学习笔记_第112张图片
尚硅谷spring boot 2核心技术学习笔记_第113张图片
尚硅谷spring boot 2核心技术学习笔记_第114张图片

2、Filter
尚硅谷spring boot 2核心技术学习笔记_第115张图片
3、Listener
尚硅谷spring boot 2核心技术学习笔记_第116张图片

7.5.2、使用RegistrationBean

ServletRegistrationBean, FilterRegistrationBean, and ServletListenerRegistrationBean

首先,将上面的组件中的这些注释掉
@WebServlet(urlPatterns = “/my”):效果:直接响应,没有经过Spring的拦截器?
@WebFilter(urlPatterns={"/css/","/images/"})
@WebListener
尚硅谷spring boot 2核心技术学习笔记_第117张图片

**
 * 1MyServlet --> /my
 * 2DispatcherServlet --> /
 */
// (proxyBeanMethods = true):保证依赖的组件始终是单实例的
@Configuration(proxyBeanMethods = true)
public class MyRegistConfig {

    @Bean
    public ServletRegistrationBean myServlet(){
        MyServlet myServlet = new MyServlet();
        return new ServletRegistrationBean(myServlet,"/my","/my02");
    }


    @Bean
    public FilterRegistrationBean myFilter(){
        MyFilter myFilter = new MyFilter();
        //拦截myServlet指定的路径
//        return new FilterRegistrationBean(myFilter,myServlet());
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        //拦截路径
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));
        return filterRegistrationBean;
    }

    @Bean
    public ServletListenerRegistrationBean myListener(){
        MySwervletContextListener mySwervletContextListener = new MySwervletContextListener();
        return new ServletListenerRegistrationBean(mySwervletContextListener);
    }
}

7.5.3、嵌入式Servlet容器

1、切换服务器
尚硅谷spring boot 2核心技术学习笔记_第118张图片
2、定制化
尚硅谷spring boot 2核心技术学习笔记_第119张图片

7.6、定制化原理

web自定义定制化(一定要掌握)
尚硅谷spring boot 2核心技术学习笔记_第120张图片

八、数据访问

8.1、SQL

1、导入JDBC场景

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-data-jdbcartifactId>
dependency>

2、导入mysql驱动


<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>8.0.26version>
dependency>

3、配置数据源——修改配置项application.yaml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_account
    username: root
    password: 75688
    driver-class-name: com.mysql.cj.jdbc.Driver

4、测试

Slf4j
@SpringBootTest
class Boot05WebAdminApplicationTests {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    void contextLoads() {

//        jdbcTemplate.queryForObject("select * from account_tbl")
//        jdbcTemplate.queryForList("select * from account_tbl",)
        Long aLong = jdbcTemplate.queryForObject("select count(*) from account_tbl", Long.class);
        log.info("记录总数:{}",aLong);

    }
}

尚硅谷spring boot 2核心技术学习笔记_第121张图片

8.2、使用Druid数据源

整合第三方技术的两种方式
● 自定义
● 找starter

8.2.1、自定义方式——基础用法

1、创建数据源

<dependency>
	<groupId>com.alibabagroupId>
    <artifactId>druidartifactId>
    <version>1.1.17version>
dependency>

2、创建配置文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_account
    username: root
    password: 75688
    driver-class-name: com.mysql.cj.jdbc.Driver

3、创建配置类

@Configuration
public class MyDataSourceConfig {

    // 默认的自动配置是判断容器中没有才会配@ConditionalOnMissingBean(DataSource.class)
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
        return druidDataSource;
    }
}

4、测试
尚硅谷spring boot 2核心技术学习笔记_第122张图片
在这里插入图片描述

8.2.2、自定义方式——开启Druid监控页功能

尚硅谷spring boot 2核心技术学习笔记_第123张图片
启动项目,访问http://localhost:8080/druid/index.html
尚硅谷spring boot 2核心技术学习笔记_第124张图片

8.2.3、自定义方式——开启监控统计功能

尚硅谷spring boot 2核心技术学习笔记_第125张图片
测试
尚硅谷spring boot 2核心技术学习笔记_第126张图片
发送sql请求
尚硅谷spring boot 2核心技术学习笔记_第127张图片
查看监控
尚硅谷spring boot 2核心技术学习笔记_第128张图片

8.2.4、自定义方式——开启web监控

尚硅谷spring boot 2核心技术学习笔记_第129张图片
代码如下

 /**
     * WebStatFilter 用于采集web-jdbc关联监控的数据。
     */
    @Bean
    public FilterRegistrationBean webStatFilter(){
        WebStatFilter webStatFilter = new WebStatFilter();

        FilterRegistrationBean<WebStatFilter> filterRegistrationBean =
                new FilterRegistrationBean<>(webStatFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));//拦截路径
        //排除一些请求路径
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");

        return filterRegistrationBean;
    }

尚硅谷spring boot 2核心技术学习笔记_第130张图片

8.2.5、自定义方式——开启防火墙

尚硅谷spring boot 2核心技术学习笔记_第131张图片

在这里插入图片描述
优化监控页——监控页面的登录
尚硅谷spring boot 2核心技术学习笔记_第132张图片
尚硅谷spring boot 2核心技术学习笔记_第133张图片

8.2.6、自定义方式——通过配置文件实现上面功能

尚硅谷spring boot 2核心技术学习笔记_第134张图片
尚硅谷spring boot 2核心技术学习笔记_第135张图片
一样能正常访问
尚硅谷spring boot 2核心技术学习笔记_第136张图片

8.2.7、找starter方式——基础用法(简单高效)

1、引入druid-starter

<dependency>
	<groupId>com.alibabagroupId>
    <artifactId>druid-spring-boot-starterartifactId>
    <version>1.1.17version>
dependency>

2、使用配置文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_account
    username: root
    password: 75688
    driver-class-name: com.mysql.cj.jdbc.Driver

    druid:
      stat-view-servlet: #监控页的配置
        enabled: true #开启配置
        login-username: admin #用户名
        login-password: 123456 #用户密码
        reset-enable: false #没有重置按钮

      web-stat-filter:
        enabled: true #开启配置
        url-pattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'

      aop-patterns: com.atguigu.admin.*  #springbean监控
      filters: stat,wall,slf4j  # 底层开启功能,stat(sql监控),wall(防火墙)

      filter: # 对上面filters里面的stat的详细配置
        stat: #sql监控
          slow-sql-millis: 1000  #超过1000毫秒就是慢查询
          logSlowSql: true  #是否记录慢查询
          enabled: true  #开启配置
          wall: #防火墙
            enabled: true #开启配置
            config:
              drop-table-allow: false #不允许删除数据库表格

  jdbc:
    template:
      query-timeout: 3 #请求超时(秒)

尚硅谷spring boot 2核心技术学习笔记_第137张图片

九、整合MyBatis操作

1、引进依赖

<dependency>
    <groupId>org.mybatis.spring.bootgroupId>
    <artifactId>mybatis-spring-boot-starterartifactId>
    <version>2.1.4version>
dependency>

9.1、配置模式(和之前的使用方法一致)

尚硅谷spring boot 2核心技术学习笔记_第138张图片
尚硅谷spring boot 2核心技术学习笔记_第139张图片
尚硅谷spring boot 2核心技术学习笔记_第140张图片
尚硅谷spring boot 2核心技术学习笔记_第141张图片
在这里插入图片描述
● 导入mybatis官方starter
● 编写mapper接口。标准@Mapper注解
● 编写sql映射文件并绑定mapper接口
● 在application.yaml中指定Mapper配置文件的位置,以及指定全局配置文件的信息 (建议;配置在mybatis.configuration)

9.2、注解模式(不需要写mapper.xml)

尚硅谷spring boot 2核心技术学习笔记_第142张图片
尚硅谷spring boot 2核心技术学习笔记_第143张图片
尚硅谷spring boot 2核心技术学习笔记_第144张图片
尚硅谷spring boot 2核心技术学习笔记_第145张图片
尚硅谷spring boot 2核心技术学习笔记_第146张图片

9.3、混合模式

尚硅谷spring boot 2核心技术学习笔记_第147张图片
在这里插入图片描述
尚硅谷spring boot 2核心技术学习笔记_第148张图片

最佳实战:
● 引入mybatis-starter
● 配置application.yaml中,指定mapper-location位置即可
● 编写Mapper接口并标注@Mapper注解
● 简单方法直接注解方式
● 复杂方法编写mapper.xml进行绑定映射
● @MapperScan(“com.atguigu.admin.mapper”) 简化,其他的接口就可以不用标注@Mapper注解

十、整合mybatis-plus

安装mybatisX插件提高开发速度
尚硅谷spring boot 2核心技术学习笔记_第149张图片
尚硅谷spring boot 2核心技术学习笔记_第150张图片

10.1、引进依赖

<dependency>
	<groupId>com.baomidougroupId>
    <artifactId>mybatis-plus-boot-starterartifactId>
    <version>3.4.1version>
dependency>

10.2、添加分页插件

尚硅谷spring boot 2核心技术学习笔记_第151张图片

@Configuration
public class MyBatisConfig {
    @Bean
    public MybatisPlusInterceptor paginationInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join

        //这是分页拦截器
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setOverflow(true);//最大页后跳回首页
        paginationInnerInterceptor.setMaxLimit(500L);//单页最大数
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);

        return mybatisPlusInterceptor;
    }
}

controller

  @GetMapping("/dynamic_table")
    public String dynamic_table(@RequestParam(value="pn",defaultValue = "1") Integer pn,Model model){
        //从数据库中查出user表中的用户进行展示

        //构造分页参数
        Page<User> page = new Page<>(pn, 2);
        //调用page进行分页,用户数据 和 分页信息都在userPage中
        Page<User> userPage = userService.page(page, null);
        model.addAttribute("users",userPage);

        return "table/dynamic_table";
    }

尚硅谷spring boot 2核心技术学习笔记_第152张图片

Service
尚硅谷spring boot 2核心技术学习笔记_第153张图片
ServiceImpl
尚硅谷spring boot 2核心技术学习笔记_第154张图片
Mapper/dao
尚硅谷spring boot 2核心技术学习笔记_第155张图片
尚硅谷spring boot 2核心技术学习笔记_第156张图片
分页
尚硅谷spring boot 2核心技术学习笔记_第157张图片

尚硅谷spring boot 2核心技术学习笔记_第158张图片

十一、单元测试

Spring Boot 2.2.0 版本开始引入 JUnit 5 作为单元测试默认库
作为最新版本的JUnit框架,JUnit5与之前版本的Junit框架有很大的不同。由三个不同子项目的几个不同模块组成。
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
JUnit Platform: Junit Platform是在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入。
JUnit Jupiter: JUnit Jupiter提供了JUnit5的新的编程模型,是JUnit5新特性的核心。内部 包含了一个测试引擎,用于在Junit Platform上运行。
JUnit Vintage: 由于JUint已经发展多年,为了照顾老的项目,JUnit Vintage提供了兼容JUnit4.x,Junit3.x的测试引擎。
尚硅谷spring boot 2核心技术学习笔记_第159张图片
注意:
SpringBoot 2.4 以上版本移除了默认对 Vintage 的依赖。如果需要兼容junit4需要自行引入(不能使用junit4的功能 @Test)
JUnit 5’s Vintage Engine Removed from spring-boot-starter-test,如果需要继续兼容junit4需要自行引入vintage

<dependency>
    <groupId>org.junit.vintagegroupId>
    <artifactId>junit-vintage-engineartifactId>
    <scope>testscope>
    <exclusions>
        <exclusion>
            <groupId>org.hamcrestgroupId>
            <artifactId>hamcrest-coreartifactId>
        exclusion>
    exclusions>
dependency>

11.1、JUnit5常用注解

● @Test :表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试
● @ParameterizedTest :表示方法是参数化测试,下方会有详细介绍
● @RepeatedTest :表示方法可重复执行,下方会有详细介绍
● @DisplayName :为测试类或者测试方法设置展示名称
● @BeforeEach :表示在每个单元测试之前执行
● @AfterEach :表示在每个单元测试之后执行
● @BeforeAll :表示在所有单元测试之前执行
● @AfterAll :表示在所有单元测试之后执行
● @Tag :表示单元测试类别,类似于JUnit4中的@Categories
● @Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore
● @Timeout :表示测试方法运行如果超过了指定时间将会返回错误
● @ExtendWith :为测试类或测试方法提供扩展类引用
● @Transactional 标注测试方法,测试完成后自动回滚

尚硅谷spring boot 2核心技术学习笔记_第160张图片
在这里插入图片描述

@SpringBootTest
@DisplayName("junit5功能测试类")
public class Junit5Test {
    @Autowired
    JdbcTemplate jdbcTemplate;

    @DisplayName("测试displayname注解")
    @Test
    void testDisplayName() {
        System.out.println(1);
        System.out.println(jdbcTemplate);
    }

    @Disabled
    @DisplayName("测试方法2")
    @Test
    void test2() {
        System.out.println(2);
    }

    @RepeatedTest(5)
    @Test
    void test3() {
        System.out.println(5);
    }

    @BeforeEach
    void testBeforeEach() {
        System.out.println("测试就要开始了...");
    }

    @AfterEach
    void testAfterEach() {
        System.out.println("测试结束了...");
    }

    @BeforeAll
    static void testBeforeAll() {
        System.out.println("所有测试就要开始了...");
    }

    @AfterAll
    static void testAfterAll() {
        System.out.println("所有测试以及结束了...");
    }
}

11.2、断言(assertions)

断定一些事情一定会发生,不发生就是有问题
断言(assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证。这些断言方法都是 org.junit.jupiter.api.Assertions 的静态方法。JUnit 5 内置的断言可以分成如下几个类别:
检查业务逻辑返回的数据是否合理。
所有的测试运行结束以后,会有一个详细的测试报告;

1、简单断言

用来对单个值进行简单的验证。如:
方法 说明
assertEquals 判断两个对象或两个原始类型是否相等
assertNotEquals 判断两个对象或两个原始类型是否不相等
assertSame 判断两个对象引用是否指向同一个对象
assertNotSame 判断两个对象引用是否指向不同的对象
assertTrue 判断给定的布尔值是否为 true
assertFalse 判断给定的布尔值是否为 false
assertNull 判断给定的对象引用是否为 null
assertNotNull 判断给定的对象引用是否不为 null

/**
     * 断言:前面断言失败,后面的代码都不会执行
     */
    @DisplayName("测试简单断言")
    @Test
    void testSimpleAssertions() {
        int cal = cal(3, 2);
        //相等
        assertEquals(6, cal, "业务逻辑计算失败");
        Object obj1 = new Object();
        Object obj2 = new Object();
        assertSame(obj1, obj2, "两个对象不一样");

    }
    int cal(int i, int j) {
        return i + j;
    }
    

2、数组断言

通过 assertArrayEquals 方法来判断两个对象或原始类型的数组是否相等

@Test
@DisplayName("array assertion")
void array() {
    assertArrayEquals(new int[]{1, 2}, new int[]{1, 2}, "数组内容不相等");
}

3、组合断言

assertAll 方法接受多个 org.junit.jupiter.api.Executable 函数式接口的实例作为要验证的断言,可以通过 lambda 表达式很容易的提供这些断言

@Test
@DisplayName("组合断言")
void all() {
    /**
     * 所有断言全部需要成功
     */
    assertAll("test",
            () -> assertTrue(true && true, "结果不为true"),
            () -> assertEquals(1, 2, "结果不是1"));

    System.out.println("=====");
}

4、异常断言

在JUnit4时期,想要测试方法的异常情况时,需要用@Rule注解的ExpectedException变量还是比较麻烦的。而JUnit5提供了一种新的断言方式Assertions.assertThrows() ,配合函数式编程就可以进行使用。

@DisplayName("异常断言")
    @Test
    void testException() {

        //断定业务逻辑一定出现异常
        assertThrows(ArithmeticException.class, () -> {
            int i = 10 / 2;
        }, "业务逻辑居然正常运行?");
    }

5、超时断言

Junit5还提供了Assertions.assertTimeout() 为测试方法设置了超时时间

/**
* 规定方法超时时间。超出时间测试出异常
*
* @throws InterruptedException
*/
@Timeout(value = 500, unit = TimeUnit.MILLISECONDS)
@Test
void testTimeout() throws InterruptedException {
   Thread.sleep(600);
}

6、 快速失败

通过 fail 方法直接使得测试失败

@DisplayName("快速失败")
@Test
void testFail(){
    //xxxxx
    if(1 == 2){
        fail("测试失败");
    }
}

11.3、 前置条件(assumptions)

JUnit 5 中的前置条件(assumptions【假设】)类似于断言,不同之处在于不满足的断言会使得测试方法失败,而不满足的前置条件只会使得测试方法的执行终止。前置条件可以看成是测试方法执行的前提,当该前提不满足时,就没有继续执行的必要。

/**
* 测试前置条件
*/
@DisplayName("测试前置条件")
@Test
void testassumptions(){
   Assumptions.assumeTrue(false,"结果不是true");
   System.out.println("111111");

}

11.4 、嵌套测试

JUnit 5 可以通过 Java 中的内部类和@Nested 注解实现嵌套测试,从而可以更好的把相关的测试方法组织在一起。在内部类中可以使用@BeforeEach 和@AfterEach 注解,而且嵌套的层次没有限制。

@DisplayName("嵌套测试")
public class TestingAStackDemo {

    Stack<Object> stack;

    @Test
    @DisplayName("new Stack()")
    void isInstantiatedWithNew() {
        new Stack<>();
        //嵌套测试情况下,外层的Test不能驱动内层的Before(After)Each/All之类的方法提前/之后运行
        assertNull(stack);
    }

    @Nested
    @DisplayName("when new")
    class WhenNew {

        @BeforeEach
        void createNewStack() {
            stack = new Stack<>();
        }

        @Test
        @DisplayName("is empty")
        void isEmpty() {
            assertTrue(stack.isEmpty());
        }

        @Test
        @DisplayName("throws EmptyStackException when popped")
        void throwsExceptionWhenPopped() {
            assertThrows(EmptyStackException.class, stack::pop);
        }

        @Test
        @DisplayName("throws EmptyStackException when peeked")
        void throwsExceptionWhenPeeked() {
            assertThrows(EmptyStackException.class, stack::peek);
        }

        @Nested
        @DisplayName("after pushing an element")
        class AfterPushing {

            String anElement = "an element";

            @BeforeEach
            void pushAnElement() {
                stack.push(anElement);
            }

            /**
             * 内层的Test可以驱动外层的Before(After)Each/All之类的方法提前/之后运行
             */
            @Test
            @DisplayName("it is no longer empty")
            void isNotEmpty() {
                assertFalse(stack.isEmpty());
            }

            @Test
            @DisplayName("returns the element when popped and is empty")
            void returnElementWhenPopped() {
                assertEquals(anElement, stack.pop());
                assertTrue(stack.isEmpty());
            }

            @Test
            @DisplayName("returns the element when peeked but remains not empty")
            void returnElementWhenPeeked() {
                assertEquals(anElement, stack.peek());
                assertFalse(stack.isEmpty());
            }
        }
    }
}

11.5、参数化测试

参数化测试是JUnit5很重要的一个新特性,它使得用不同的参数多次运行测试成为了可能,也为我们的单元测试带来许多便利。

利用@ValueSource等注解,指定入参,我们将可以使用不同的参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码。

@ValueSource: 为参数化测试指定入参来源,支持八大基础类以及String类型,Class类型
@NullSource: 表示为参数化测试提供一个null的入参
@EnumSource: 表示为参数化测试提供一个枚举入参
@CsvFileSource:表示读取指定CSV文件内容作为参数化测试入参
@MethodSource:表示读取指定方法的返回值作为参数化测试入参(注意方法返回需要是一个流)

当然如果参数化测试仅仅只能做到指定普通的入参还达不到让我觉得惊艳的地步。让我真正感到他的强大之处的地方在于他可以支持外部的各类入参。如:CSV,YML,JSON 文件甚至方法的返回值也可以作为入参。只需要去实现ArgumentsProvider接口,任何外部文件都可以作为它的入参。

@ParameterizedTest
@DisplayName("参数化测试")
@ValueSource(ints = {1,2,3,4,5})
void testParameterized(int i){
    System.out.println(i);
}

@ParameterizedTest
@DisplayName("参数化测试")
@MethodSource("stringProvider")
void testParameterized2(String i){
    System.out.println(i);
}

static Stream<String> stringProvider() {
    return Stream.of("apple", "banana","atguigu");
}

11.6、迁移指南

在进行迁移的时候需要注意如下的变化:
● 注解在 org.junit.jupiter.api 包中,断言在 org.junit.jupiter.api.Assertions 类中,前置条件在 org.junit.jupiter.api.Assumptions 类中。
● 把@Before 和@After 替换成@BeforeEach 和@AfterEach。
● 把@BeforeClass 和@AfterClass 替换成@BeforeAll 和@AfterAll。
● 把@Ignore 替换成@Disabled。
● 把@Category 替换成@Tag。
● 把@RunWith、@Rule 和@ClassRule 替换成@ExtendWith。

十二、指标监控

12.1、SpringBoot Actuator

简介
未来每一个微服务在云上部署以后,我们都需要对其进行监控、追踪、审计、控制等。SpringBoot就抽取了Actuator场景,使得我们每个微服务快速引用即可获得生产级别的应用监控、审计等功能。

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-actuatorartifactId>
dependency>

如何使用
● 引入场景
● 访问 http://localhost:8080/actuator/**
暴露所有监控信息为HTTP

management:
  endpoints:
    enabled-by-default: true #暴露所有端点信息
    web:
      exposure:
        include: '*'  #以web方式暴露

● 测试
http://localhost:8080/actuator/beans
http://localhost:8080/actuator/configprops
http://localhost:8080/actuator/metrics
http://localhost:8080/actuator/metrics/jvm.gc.pause
http://localhost:8080/actuator/endpointName/detailPath
。。。。。。

12.2、Actuator Endpoint

1、最常使用的端点
auditevents 暴露当前应用程序的审核事件信息。需要一个AuditEventRepository组件。
beans 显示应用程序中所有Spring Bean的完整列表。
caches 暴露可用的缓存。
conditions 显示自动配置的所有条件信息,包括匹配或不匹配的原因。
configprops 显示所有@ConfigurationProperties。
env 暴露Spring的属性ConfigurableEnvironment
flyway 显示已应用的所有Flyway数据库迁移。
需要一个或多个Flyway组件。
health 显示应用程序运行状况信息。
httptrace 显示HTTP跟踪信息(默认情况下,最近100个HTTP请求-响应)。需要一个HttpTraceRepository组件。
info 显示应用程序信息。
integrationgraph 显示Spring integrationgraph 。需要依赖spring-integration-core。
loggers 显示和修改应用程序中日志的配置。
liquibase 显示已应用的所有Liquibase数据库迁移。需要一个或多个Liquibase组件。
metrics 显示当前应用程序的“指标”信息。
mappings 显示所有@RequestMapping路径列表。
scheduledtasks 显示应用程序中的计划任务。
sessions 允许从Spring Session支持的会话存储中检索和删除用户会话。需要使用Spring Session的基于Servlet的Web应用程序。
shutdown 使应用程序正常关闭。默认禁用。
startup 显示由ApplicationStartup收集的启动步骤数据。需要使用SpringApplication进行配置BufferingApplicationStartup。
threaddump 执行线程转储。

如果您的应用程序是Web应用程序(Spring MVC,Spring WebFlux或Jersey),则可以使用以下附加端点:

heapdump 返回hprof堆转储文件。
jolokia 通过HTTP暴露JMX bean(需要引入Jolokia,不适用于WebFlux)。需要引入依赖jolokia-core。
logfile 返回日志文件的内容(如果已设置logging.file.name或logging.file.path属性)。支持使用HTTPRange标头来检索部分日志文件的内容。
prometheus 以Prometheus服务器可以抓取的格式公开指标。需要依赖micrometer-registry-prometheus。

最常用的Endpoint
● Health:监控状况
● Metrics:运行时指标
● Loggers:日志记录

十三、常用技巧

13.1、application

修改端口号:server.port=8081
在这里插入图片描述

13.2、网站

尚硅谷spring boot 2核心技术学习笔记_第161张图片

13.3、使用JSR303进行数据校验

尚硅谷spring boot 2核心技术学习笔记_第162张图片
尚硅谷spring boot 2核心技术学习笔记_第163张图片

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号