SpringBoot学习笔记

关于SpringBoot的学习笔记,视频来自雷丰阳SpringBoot2021

基础入门

1.SpringBoot概述

SpringBoot的底层是SpringFramework

什么是适配器模式?

SpringBoot优点

微服务将一大应用拆分成小模块,每个小模块都可以独立部署到服务器上
微服务拆分后会出现分布式问题,这时候就使用SpringBoot + SpringCloud的解决方案

依赖管理

场景启动器的基础是spring-boot-starter,它包含许多其他依赖,这些依赖定义了版本,因此你要引入这些依赖可以不用定义版本信息。如果是非其他依赖,需要定义版本信息

springboot的application启动类就是一个IOC,配置好了许多组件,如支持Spring MVC的多个组件等

包扫描:application所在的包自动扫描容器
想要改变扫描路径,@SpringBootApplication(scanBasePackages=”com.atguigu”)

组件添加【底层注解】

@proxyBeanMethods:代理bean的方法
Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】

@Import({User.class, DBHelper.class})
给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
条件装配:满足@Conditional指定的条件,则进行组件注入

@ImportResource支持导入Spring的配置文件

JavaBean和配置文件中的属性绑定

@Component注解表示该类是一个组件类

自动配置

SpringBoot启动默认加载所有的自动配置项,按照条件装配最终会被按需加载

2.开发小技巧

1 Lombok

1
2
3
4
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@NoArgsConstructor   //无参构造器
@AllArgsConstructor //所有成员变量的有参构造器,如需定制,可以自己手动编写代码
@Data //get、set方法
@ToString //toString方法
@EqualsAndHashCode //重写equals和hashcode
public class User {

private String name;
private Integer age;

private Pet pet;

public User(String name,Integer age){
this.name = name;
this.age = age;
}


}

lombok还提供@Slf4j注解,用于日志打印。如果需要使用lombok,需要引入依赖

2 dev-tools

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>

项目或者页面修改以后:Ctrl+F9; 跟shift+F9效果差不多,它的功能也是重启项目

核心功能

1.配置文件

yaml配置文件,k v格式,k v之间必须要有空格
properties的优先级比yml高
\n 双引号会换行,单引号不会换行
maven的clean+package导出jar包,jar包是项目可执行的文件,java -jar启动

2.Web开发

SpringBoot几乎提供了所有的自动配置

2.1 静态资源目录

只要静态资源放在类路径下: called /static (or /public or /resources or /META-INF/resources
访问 : 当前项目根路径/ + 静态资源名

原理: 静态映射/**。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面

改变默认的静态资源路径

1
2
3
4
5
6
spring:
mvc:
static-path-pattern: /res/**

resources:
static-locations: [classpath:/haha/]

静态资源前缀的设置,会导致静态资源中index和favicon的失效

2.2 请求映射

所有的请求映射都在HandlerMapping中。

  • SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;
  • SpringBoot自动配置了默认 的 RequestMappingHandlerMapping
  • 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。
    • 如果有就找到这个请求对应的handler
    • 如果没有就是下一个 HandlerMapping
  • 我们需要一些自定义的映射处理,我们也可以自己给容器中放HandlerMapping。自定义 HandlerMapping

2.3 请求处理

矩阵变量必须有url路径变量才能被解析

参数解析器的理解

2.4 POJO的封装过程

数据绑定

2.5 数据响应与内容协商

3.Thymeleaf

前端模板引擎,用于springboot的前后端不分离项目

后端向前端html传递数据,可以把数据放在HttpSession和Model对象中
session存在服务器,cookie存在客户端

用户是否登录使用拦截器的解决方案

创建list的user对象的方法:

4.拦截器

写完拦截器后,还要写一个配置类

log日志打印用大括号{},后面可以传参数到大括号中

5.文件上传

使用@RequestPart注解
文件上传API Multipart接口可以在配置文件中设置单个文件上传大小、整体文件上传大小
一般设置单个文件上传大小为10M

6.异常处理

前端需要设置404、5xx错误跳转页面。后端编写全局异常处理跳转代码

异常处理自动配置ErrorMvcAutoConfiguration

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

SpringBoot场景的正常运行得益于底层的自动配置

定制化原理
如果接管SpringMVC,就要全面定义它底层的行为

8.数据访问

8.1 JDBCTempalte


数据库驱动?
为什么导入JDBC场景,官方不导入驱动?官方不知道我们接下要操作什么数据库。
数据库版本和驱动版本对应

1
2
3
4
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

SpringBoot默认使用的是Hikari数据源,配置文件配置数据源的时候不用去配置,因为底层已经指定帮我们配好了。如果需要更换数据源,也可以进行配置

使用JdbcTemplate模板引擎,就可以操作数据库了

使用某个中间件:首先要找starter,starter会把需要用到的组件都注入到容器中,我们只需要进行一些配置,就可以使用这些中间件了

目前比较流行的数据源是Hikari和Druid

自定义整合Druid数据源:
Druid提供内置监控页的功能,在配置文件中配置即可查看页面


Arrays.asList() 创建一个集合

如果某个中间有starter启动类,就不用自己创建配置类进行配置了。所以用中间件之前,先引入starter,比如druid就有starter

druid的监控页可以配置账号密码

8.2 MyBatis

引入MyBatis的依赖

1
2
3
4
5
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>

MyBatis开启驼峰命名规则,否则数据库带_的字段无法正常读取
mybatis-config.xml可以不写,配置直接写在application.properties中即可
mapper接口标注@Mapper注解

sql语句可以用xml的方式,也可以用注解的方式

8.3 MyBatis Plus

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

1
2
3
4
5
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>

mapper接口继承BaseMapper,不用自己编写xml文件

MyBatis Plus的pojo类示例:

@TableField表示该字段不在数据库中
Service的实现类需要加@Service注解

MyBatis Plus在mapper层和service层都进行了简化,提供了基础的方法,并且自己不用写xml文件


ctrl + F12可以查看类结构,由于继承了ServiceImpl,可以看到由MyBatis Plus已经实现的方法

实现分页查询,创建Page对象,然后使用提供的分页查询方法。想要分页完成,需要整合分页插件

MyBatis Plus结合Thymeleaf完成分页查询

8.4 Redis

redis-starter由官方整合,由官方整合的starter自动配置都在统一的一个包中可以进行查看

使用RedisTemplate即可操作Redis,对Redis中的数据进行增加、修改、删除等操作

9.单元测试

当前主要是JUnit5,相比于JUnit4使用起来更方便。SpringBoot2.4之后就不允许使用JUnit4了


以上这种单元测试使用起来非常方便

JUnit5的相关注解:

断言机制
不满足的断言会使测试条件失败

前制条件

嵌套测试

参数化测试
使用不同的参数多次运行某个测试 @ValueSource

10.指标监控

SpringBoot Actuator


整合SpringBoot Admin Server:开源的应用监控可视化项目
可以用来查看应用的启动状态、内存占用、cpu使用率等

11.原理解析

11.1 Profile配置环境切换

从配置文件取值,@Value加冒号,冒号后面表示如果不到值,赋予一个默认值

如果两个配置文件中有相同的配置,以指定环境的配置为主

打包一般使用clean install,install包含了package的功能

11.2 自定义starter

SpringBoot也可以自定义starter

11.3 SpringBoot启动过程

  • 创建 SpringApplication
    • 保存一些信息。
    • 判定当前应用的类型。ClassUtils。Servlet
    • bootstrappers:初始启动引导器(List**):去spring.factories文件中找 **org.springframework.boot.Bootstrapper
    • ApplicationContextInitializer;去spring.factories找 ApplicationContextInitializer
      • List<ApplicationContextInitializer<?>> initializers
    • 找 ApplicationListener ;应用监听器。spring.factories找 ApplicationListener
      • List<ApplicationListener<?>> listeners
  • 运行 SpringApplication
    • StopWatch
    • 记录应用的启动时间
    • 创建引导上下文(Context环境)createBootstrapContext()
      • 获取到所有之前的 **bootstrappers 挨个执行 **intitialize() 来完成对引导启动器上下文环境设置
    • 让当前应用进入headless模式。java.awt.headless
    • 获取所有 RunListener(运行监听器)【为了方便所有Listener进行事件感知】
      • getSpringFactoriesInstances 去spring.factories找 SpringApplicationRunListener.
    • 遍历 SpringApplicationRunListener 调用 starting 方法;
      • 相当于通知所有感兴趣系统正在启动过程的人,项目正在 starting。
    • 保存命令行参数;ApplicationArguments
    • 准备环境 prepareEnvironment();
      • 返回或者创建基础环境信息对象。StandardServletEnvironment
      • 配置环境信息对象。
        • 读取所有的配置源的配置属性值。
      • 绑定环境信息
      • 监听器调用 listener.environmentPrepared();通知所有的监听器当前环境准备完成
    • 创建IOC容器(createApplicationContext())
      • 根据项目类型(Servlet)创建容器,
      • 当前会创建 AnnotationConfigServletWebServerApplicationContext
    • **准备ApplicationContext IOC容器的基本信息 **  prepareContext()
      • 保存环境信息
      • IOC容器的后置处理流程。
      • 应用初始化器;applyInitializers;
        • 遍历所有的 ApplicationContextInitializer 。调用 initialize.。来对ioc容器进行初始化扩展功能
        • 遍历所有的 listener 调用 contextPrepared。EventPublishRunListenr;通知所有的监听器contextPrepared
      • 所有的监听器 调用 contextLoaded。通知所有的监听器 contextLoaded;
    • 刷新IOC容器。refreshContext
      • 创建容器中的所有组件(Spring注解)
    • 容器刷新完成后工作?afterRefresh
    • 所有监听 器 调用 listeners.started(context); 通知所有的监听器 started
    • 调用所有runners;callRunners()
      • 获取容器中的 **ApplicationRunner **
      • 获取容器中的 CommandLineRunner
      • 合并所有runner并且按照@Order进行排序
      • 遍历所有的runner。调用 run 方法
    • 如果以上有异常,
      • 调用Listener 的 failed
    • **调用所有监听器的 running 方法 **listeners.running(context); **通知所有的监听器 running **
    • running如果有问题。继续通知 failed 。调用所有 Listener 的 failed;通知所有的监听器 failed