springboot学习笔记
目录
- 前言
- 1 基础入门
-
- 1.1 spring生态圈
- 1.2 springboot---HelloWorld
- 1.3 springboot--依赖管理特性
- 1.4 springboot---自动配置特性
- 1.5 底层注解 --- @Configuration详解
- 1.6 底层注解 --- @Import导入组件
- 1.7 底层注解 --- @Conditional条件装配
- 1.8 底层注解-@ImportResource导入Spring配置文件
- 1.9 底层注解-@ConfigurationProperties配置绑定
- 1.10 自动配置【源码分析】-自动包规则原理
- 1.11 最佳实践-SpringBoot应用如何编写
- 1.12 最佳实战---Lombok简化开发
- 1.13 最佳实践-dev-tools
- 1.14 最佳实践-Spring Initailizr
- 1.15 配置文件-yaml的用法
- 1.16 配置文件-自定义类绑定的配置提示
- 2 web场景第一部分
-
- 2.1 开发简介
- 2.2 静态资源规则与定制化
- 2.3 welcome与favicon功能
- 2.4 请求处理 --- Rest映射及源码解析
- 2.5 请求处理-常用参数注解使用
- 2.6 请求处理-@RequestAttribute
- 2.7 请求处理-@MatrixVariable与UrlPathHelper
- 2.8 请求处理-【源码分析】-各种类型参数解析原理
- 2.9 请求处理-【源码分析】-Servlet API参数解析原理
- 2.10 请求处理-【源码分析】-Model、Map原理
- 2.11 请求处理-【源码分析】-自定义参数绑定原理
- 2.12 请求处理-【源码分析】-自定义Converter原理
- 2.13 响应处理-【源码分析】-ReturnValueHandler原理
- 2.14 响应处理-【源码分析】-HTTPMessageConverter原理
- 2.15 响应处理-【源码分析】-内容协商原理
- 2.16 响应处理-【源码分析】-基于请求参数的内容协商原理
- 2.17 响应处理-【源码分析】-自定义MessageConverter
- 2.18 响应处理-【源码分析】-浏览器与PostMan内容协商完全适配
- 3 Web之视图解析
-
- 3.1 Thymeleaf初体验
- 3.2 web实验-后台管理系统基本功能
-
- 3.2.1 项目创建
- 3.2.2 登陆页面
- 3.2.3 登录控制层
- 3.2.4 模型
- 3.2.5 抽取公共页面
- 3.2.6 遍历数据与页面bug修改
- 3.2.7 视图解析-【源码分析】-视图解析器与视图
- 3.2.8 拦截器-登录检查与静态资源放行
- 3.2.9 拦截器-【源码分析】-拦截器的执行时机和原理
- 3.2.10 文件上传-单文件与多文件上传的使用
- 3.2.11 文件上传-【源码流程】文件上传参数解析器
- 3.2.12 错误处理-SpringBoot默认错误处理机制
- 3.2.13 错误处理-【源码分析】底层组件功能分析
- 3.2.14 错误处理-【源码流程】异常处理流程
- 3.2.15 错误处理-【源码流程】几种异常处理原理
- 3.2.16 原生组件注入-原生注解与Spring方式注入
- 3.2.17 使用原生的注解
- 3.2.18 Spring方式注入
- 3.2.19 原生组件注入-【源码分析】DispatcherServlet注入原理
- 3.2.20 嵌入式Servlet容器-【源码分析】切换web服务器与定制化
- 3.2.21 定制Servlet容器
- 3.2.22 定制化原理-SpringBoot定制化组件的几种方式(小结)
- 3.2.23 数据访问-数据库场景的自动配置分析与整合测试
- 3.2.24 数据访问-自定义方式整合druid数据源
- 3.2.25 注意
- 3.2.26 数据访问-druid数据源starter整合方式
- 3.2.27 数据访问-整合MyBatis-配置版
- 3.2.28 数据访问-整合MyBatis-注解配置混合版
- 3.2.29 数据访问-整合MyBatisPlus操作数据库
- 3.2.30 数据访问-CRUD实验-数据列表展示
- 数据访问-CRUD实验-分页数据展示
- 3.2.31 数据访问-CRUD实验-删除用户完成
- 3.2.32 数据访问-准备阿里云Redis环境
- 3.2.33 数据访问-Redis操作与统计小实验
- 后记
前言
让我们跟随尚硅谷雷丰阳老师的讲解步入springboot2的学习中。源码部分留待工作之后有实际开发经验再来啃。
1 基础入门
1.1 spring生态圈
1.1.1 spirng能做什么
- web开发
- 数据访问
- 安全控制
- 分布式
- 消息服务
- 移动开发
- 批处理
- …
spring5重大升级
1.1.2 为什么用SpringBoot
能快速创建出生产级别的Spring应用。
springboot优点
-
Create stand-alone Spring applications
- 创建独立Spring应用
-
Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
- 内嵌web服务器
-
Provide opinionated ‘starter’ dependencies to simplify your build configuration
- 自动starter依赖,简化构建配置
-
Automatically configure Spring and 3rd party libraries whenever possible
- 自动配置Spring以及第三方功能
-
Provide production-ready features such as metrics, health checks, and externalized configuration
- 提供生产级别的监控、健康检查及外部化配置
-
Absolutely no code generation and no requirement for XML configuration
- 无代码生成、无需编写XML
-
SpringBoot是整合Spring技术栈的一站式框架
-
SpringBoot是简化Spring技术栈的快速开发脚手架
springboot缺点
- 人称版本帝,迭代快,需要时刻关注变化
- 封装太深,内部原理复杂,不容易精通
1.1.3 springboot的大时代背景
微服务
- 微服务是一种架构风格
- 一个应用拆分为一组小型服务
- 每个服务运行在自己的进程内,也就是可独立部署和升级
- 服务之间使用轻量级HTTP交互
- 服务围绕业务功能拆分
- 可以由全自动部署机制独立部署
- 去中心化,服务自治。服务可以使用不同的语言、不同的存储技术
分布式
- 远程调用
- 服务发现
- 负载均衡
- 服务容错
- 配置管理
- 服务监控
- 链路追踪
- 日志管理
- 任务调度
- …
分布式的解决
上云的困难
- 服务自愈
- 弹性伸缩
- 服务隔离
- 自动化部署
- 灰度发布
- 流量治理
- …
1.1.4 springboot官方文档架构
官网文档架构
查看版本新特性
1.2 springboot—HelloWorld
1.2.1 系统要求
- Java 8
- Maven 3.3+
1.2.2 Maven配置文件
在maven安装目录下的conf目录下的settings.xml文件中修改:添加阿里云配置源和修改jdk版本为java8及以上。
1.2.3 具体步骤
创建maven工程
[1] 引入依赖
[2] 创建主程序
[3] 编写业务
[4] 运行&测试
- 运行
MainApplication
类 - 浏览器输入
http://localhost:8888/hello
,将会输出Hello, Spring Boot 2!
。
[5] 注意
启动出现这个问题:> This application has no explicit mapping for /error, so you are seeing this
解决方法:Application启动类的位置不对.要将Application类放在最外侧,即包含所有子包
放在boot里面启动就会不行。
[6] 设置配置
maven工程的resource文件夹中创建application.properties文件。
[7] 打包部署
在pom.xml添加
在IDEA的Maven插件上点击运行 clean 、package,把helloworld工程项目的打包成jar包,
打包好的jar包被生成在helloworld工程项目的target文件夹内。
用cmd运行java -jar boot-01-helloworld-1.0-SNAPSHOT.jar
,既可以运行helloworld工程项目。
将jar包直接在目标服务器执行即可。
1.3 springboot–依赖管理特性
- 父项目做依赖管理
开发导入starter场景启动器
- 见到很多 spring-boot-starter-* : *就某种场景
- 只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
- 更多SpringBoot所有支持的场景
- 见到的 *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
-
无需关注版本号,自动版本仲裁
- 引入依赖默认都可以不写版本
- 引入非版本仲裁的jar,要写版本号。
-
可以修改默认版本号
- 查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
- 在当前项目里面重写配置,如下面的代码。
1.4 springboot—自动配置特性
-
自动配好Tomcat
- 引入Tomcat依赖
- 配置Tomcat
-
自动配好SpringMVC
- 引入SpringMVC全套组件
- 自动配好SpringMVC常用组件(功能)
-
自动配好Web常见功能,如:字符编码问题
- SpringBoot帮我们配置好了所有web开发的常见场景
-
默认的包结构
- 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
- 无需以前的包扫描配置
- 想要改变扫描路径
- @SpringBootApplication(scanBasePackages=“com.lun”)
- @ComponentScan 指定扫描路径
-
各种配置拥有默认值
- 默认配置最终都是映射到某个类上,如:
MultipartProperties
- 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
- 默认配置最终都是映射到某个类上,如:
-
按需加载所有自动配置项
- 非常多的starter
- 引入了哪些场景这个场景的自动配置才会开启
- SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
-
…
1.5 底层注解 — @Configuration详解
-
基本使用
- Full模式与Lite模式
- 示例
实体1
实体2
原来我们进行ioc容器组件注入使用的都是beans.xml这个文件
在使用springboot之后我们可以创建一个配置类来代替上面的beans.xml这个文件。
@Configuration测试代码如下:
配置类
-
最佳实战
- 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
- 配置 类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式(默认)
1.6 底层注解 — @Import导入组件
@Import({User.class, DBHelper.class})给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
1.7 底层注解 — @Conditional条件装配
条件装配:满足Conditional指定的条件,则进行组件注入
俩个作用:根据当前环境或者容器情况来动态注入bean,要配合@Bean使用
@ConditionalOnMissingBean作用:判断当前需要注入Spring容器中的bean的实现类是否已经含有,有的话不注入,没有就注入
@ConditionalOnBean作用:判断当前需要注册的bean的实现类否被spring管理,如果被管理则注入,反之不注入
简单来说:@ConditionalOnBean(“xxx”) springioc容器中有这个组件,就进行注入。因为一个配置类中不一定只有一个组件,可能要注册多个组件,当我们的在类上标注之后,只要容器中有这个组件,那么这个类就会生效,从而进行其他组件的注册。
@ConditionalOnMissingBean(“xxx”) springioc容器中没有这个组件的话才注入,有就不注入。在底层源码中经常使用。如果我们自己定义了一个拦截器,因为使用的是这个注解,那么因为容器中已经有了,所以就使用我们自己的。如果没有,就使用默认帮助我们进行注入。这是自动装配的底层源码实现。
1.8 底层注解-@ImportResource导入Spring配置文件
比如,公司使用bean.xml文件生成配置bean,然而你为了省事,想继续复用bean.xml,@ImportResource粉墨登场。
beans.xml:
使用方法:
测试类:
1.9 底层注解-@ConfigurationProperties配置绑定
如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用.
对于一个javabean,我们创建类之后,要进行属性的配置的话,我们可以使用properties文件来进行属性的设置。这个时候面临一个问题,如果使用传统的方法来进行读取的话肯定是可以的。
传统方法
其实我们不难发现,上面的方法是比较麻烦的,在springboot中如何使用注解方式进行注入呢?
第一种方式:
使用@Compoent
+ @ConfigurationProperties
,使用@Compoent
这个主要是因为只有在spring容器中才会有这些功能,所以第一步就是要在类上将其注入到spring容器中,然后来使用。
第二种方式:
如果我们在类上面不加@Compoent
,那么要如何才能使用呢?
@EnableConfigurationProperties + @ConfigurationProperties,使用@EnableConfigurationProperties
这个来进行既可,注意这个注解要放在配置类上才行,这个注解会帮助我们将car这个类注入到容器中,然后在原来的Car这个类上使用原来的@ConfigurationProperties这个注解。
1.10 自动配置【源码分析】-自动包规则原理
SpringBoot默认会在底层配好所有的组件,但是如果用户自己配置了以用户的优先。
总结:
- SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
- 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。(xxxxProperties里面读取,xxxProperties和配置文件进行了绑定)
- 生效的配置类就会给容器中装配很多组件
- 只要容器中有这些组件,相当于这些功能就有了
- 定制化配置
- 用户直接自己@Bean替换底层的组件
- 用户去看这个组件是获取的配置文件什么值就去修改。
xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 ----> application.properties
1.11 最佳实践-SpringBoot应用如何编写
- 引入场景依赖
- 查看自动配置了哪些(选做)
- 自己分析,引入场景对应的自动配置一般都生效了
- 配置文件中debug=true开启自动配置报告。
- Negative(不生效)
- Positive(生效)
- 是否需要修改
- 参照文档修改配置项
- 官方文档
- 自己分析。xxxxProperties绑定了配置文件的哪些。
- 自定义加入或者替换组件
- @Bean、@Component…
- 自定义器 XXXXXCustomizer;
- …
- 参照文档修改配置项
1.12 最佳实战—Lombok简化开发
Lombok用标签方式代替构造器、getter/setter、toString()等鸡肋代码。
spring boot已经管理Lombok。引入依赖:
IDEA中File->Settings->Plugins,搜索安装Lombok插件。
简化日志开发
1.13 最佳实践-dev-tools
添加依赖:
在IDEA中,项目或者页面修改以后:Ctrl+F9。
1.14 最佳实践-Spring Initailizr
Spring Initailizr是创建Spring Boot工程向导。
在IDEA中,菜单栏New -> Project -> Spring Initailizr。
1.15 配置文件-yaml的用法
同以前的properties用法
YAML 是 “YAML Ain’t Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。
非常适合用来做以数据为中心的配置文件。
[1] 基本语法
- key: value;kv之间有空格
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- '#'表示注释
- 字符串无需加引号,如果要加,单引号’'、双引号""表示字符串内容会被 转义、不转义
[2] 数据类型
- 字面量:单个的、不可再分的值。date、boolean、string、number、null
- 对象:键值对的集合。map、hash、set、object
- 数组:一组按次序排列的值。array、list、queue
[3] 实例
用yaml表示以上对象
1.16 配置文件-自定义类绑定的配置提示
我们在编写yaml文件的时候发现只有spring这类的才有提示,我们自己定义的没有提示,这个其实也是可以导入依赖设置的。
2 web场景第一部分
2.1 开发简介
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.(大多场景我们都无需自定义配置)
The auto-configuration adds the following features on top of Spring’s defaults:
-
Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans.- 内容协商视图解析器和BeanName视图解析器
-
Support for serving static resources, including support for WebJars (covered later in this document)).
- 静态资源(包括webjars)
-
Automatic registration of
Converter
,GenericConverter
, andFormatter
beans.- 自动注册
Converter,GenericConverter,Formatter
- 自动注册
-
Support for
HttpMessageConverters
(covered later in this document).- 支持
HttpMessageConverters
(后来我们配合内容协商理解原理)
- 支持
-
Automatic registration of
MessageCodesResolver
(covered later in this document).- 自动注册
MessageCodesResolver
(国际化用)
- 自动注册
-
Static
index.html
support.- 静态index.html 页支持
-
Custom
Favicon
support (covered later in this document).- 自定义
Favicon
- 自定义
-
Automatic use of a
ConfigurableWebBindingInitializer
bean (covered later in this document).- 自动使用
ConfigurableWebBindingInitializer
,(DataBinder负责将请求数据绑定到JavaBean上)
- 自动使用
If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own
@Configuration
class of typeWebMvcConfigurer
but without@EnableWebMvc
.不用@EnableWebMvc注解。使用
@Configuration
+WebMvcConfigurer
自定义规则
If you want to provide custom instances of
RequestMappingHandlerMapping
,RequestMappingHandlerAdapter
, orExceptionHandlerExceptionResolver
, and still keep the Spring Boot MVC customizations, you can declare a bean of typeWebMvcRegistrations
and use it to provide custom instances of those components.声明
WebMvcRegistrations
改变默认底层组件
If you want to take complete control of Spring MVC, you can add your own
@Configuration
annotated with@EnableWebMvc
, or alternatively add your own@Configuration
-annotatedDelegatingWebMvcConfiguration
as described in the Javadoc of@EnableWebMvc
.使用
@EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration 全面接管SpringMVC
2.2 静态资源规则与定制化
[1] 静态资源目录
只要静态资源放在类路径下: called /static
(or /public
or /resources
or /META-INF/resources
访问 : 当前项目根路径/ + 静态资源名
原理: 静态映射/**。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面。
也可以改变默认的静态资源路径,/static
,/public
,/resources
, /META-INF/resources
失效
[2] 静态资源访问前缀
当前项目 + static-path-pattern + 静态资源名 = 静态资源文件夹下找.
[3] webjar
可用jar方式添加css,js等资源文件,
例如,添加jquery
访问地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js 后面地址要按照依赖里面的包路径。
2.3 welcome与favicon功能
[1] 欢迎页支持
-
静态资源路径下 index.html。
- 可以配置静态资源路径
- 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
- controller能处理/index。
[2] 自定义Favicon
指网页标签上的小图标。
favicon.ico 放在静态资源目录下即可。
2.4 请求处理 — Rest映射及源码解析
[1] 请求映射
-
@xxxMapping;
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
-
Rest风格支持(使用HTTP请求方式动词来表示对资源的操作)
- 以前:
- /getUser 获取用户
- /deleteUser 删除用户
- /editUser 修改用户
- /saveUser保存用户
- 现在: /user
- GET-获取用户
- DELETE-删除用户
- PUT-修改用户
- POST-保存用户
- 核心Filter;HiddenHttpMethodFilter
- 以前:
-
用法
- 开启页面表单的Rest功能
- 页面 form的属性method=post,隐藏域 _method=put、delete等(如果直接get或post,无需隐藏域)
- 编写请求映射
- Rest原理(表单提交要使用REST的时候)
- 表单提交会带上
\_method=PUT
- 请求过来被
HiddenHttpMethodFilter
拦截- 请求是否正常,并且是POST
- 获取到
\_method
的值。 - 兼容以下请求;PUT.DELETE.PATCH
- 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
- 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。
- 获取到
- 请求是否正常,并且是POST
-
Rest使用客户端工具。
- 如PostMan可直接发送put、delete等方式请求。
[2] 怎么改变默认的_method
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
意味着在没有HiddenHttpMethodFilter
时,才执行hiddenHttpMethodFilter()
。因此,我们可以自定义filter,改变默认的\_method
。例如:
将\_method
改成_m
。
所有的请求映射都在HandlerMapping中:
-
SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;
-
SpringBoot自动配置了默认 的 RequestMappingHandlerMapping
-
请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。
- 如果有就找到这个请求对应的handler
- 如果没有就是下一个 HandlerMapping
-
我们需要一些自定义的映射处理,我们也可以自己给容器中放HandlerMapping。自定义 HandlerMapping
2.5 请求处理-常用参数注解使用
注解:
@PathVariable
路径变量@RequestHeader
获取请求头@RequestParam
获取请求参数(指问号后的参数,url?a=1&b=2)@CookieValue
获取Cookie值@RequestAttribute
获取request域属性@RequestBody
获取请求体[POST]@MatrixVariable
矩阵变量@ModelAttribute
使用示例:
2.6 请求处理-@RequestAttribute
用法:
获取请求域中保存的属性的。我们给request域中设置属性一般是在页面转发的时候取出请求域中的数据。
2.7 请求处理-@MatrixVariable与UrlPathHelper
-
语法: 请求路径:
/cars/sell;low=34;brand=byd,audi,yd
-
SpringBoot默认是禁用了矩阵变量的功能
- 手动开启:原理。对于路径的处理。UrlPathHelper的removeSemicolonContent设置为false,让其支持矩阵变量的。
-
矩阵变量必须有url路径变量才能被解析
手动开启矩阵变量:
- 实现
WebMvcConfigurer
接口:
- 创建返回
WebMvcConfigurer
Bean:
@MatrixVariable
的用例
2.8 请求处理-【源码分析】-各种类型参数解析原理
这要从DispatcherServlet
开始说起:
HandlerMapping
中找到能处理请求的Handler
(Controller.method())。- 为当前Handler 找一个适配器
HandlerAdapter
,用的最多的是RequestMappingHandlerAdapter。 - 适配器执行目标方法并确定方法参数的每一个值。
[1] HandlerAdapter
默认会加载所有HandlerAdapter
有这些HandlerAdapter
:
-
支持方法上标注
@RequestMapping
-
支持函数式编程的
-
…
-
…
[2] 执行目标方法
HandlerAdapter
接口实现类RequestMappingHandlerAdapter
(主要用来处理@RequestMapping
)
[3] 参数解析器
确定将要执行的目标方法的每一个参数的值是什么;
SpringMVC目标方法能写多少种参数类型。取决于参数解析器argumentResolvers。
this.argumentResolvers
在afterPropertiesSet()
方法内初始化
HandlerMethodArgumentResolverComposite
类如下:(众多参数解析器argumentResolvers的包装类)。
我们看看HandlerMethodArgumentResolver
的源码:
[4] 返回值处理器
ValueHandler
this.returnValueHandlers
在afterPropertiesSet()
方法内初始化
HandlerMethodReturnValueHandlerComposite
类如下:
HandlerMethodReturnValueHandler
接口:
[5] 回顾执行目标方法
RequestMappingHandlerAdapter
的handle()
方法:
RequestMappingHandlerAdapter
的invokeHandlerMethod()
方法:
invokeAndHandle()
方法如下:
[6] 如何确定目标方法每一个参数的值
重点分析ServletInvocableHandlerMethod
的getMethodArgumentValues
方法
this.resolvers
的类型为HandlerMethodArgumentResolverComposite
(在参数解析器章节提及)
[7] 小结
本节描述,一个请求发送到DispatcherServlet后的具体处理流程,也就是SpringMVC的主要原理。
本节内容较多且硬核,对日后编程很有帮助,需耐心对待。
可以运行一个示例,打断点,在Debug模式下,查看程序流程。
2.9 请求处理-【源码分析】-Servlet API参数解析原理
- WebRequest
- ServletRequest
- MultipartRequest
- HttpSession
- javax.servlet.http.PushBuilder
- Principal
- InputStream
- Reader
- HttpMethod
- Locale
- TimeZone
- ZoneId
ServletRequestMethodArgumentResolver用来处理以上的参数
用例:
2.10 请求处理-【源码分析】-Model、Map原理
复杂参数:
-
Map
-
Model(map、model里面的数据会被放在request的请求域 request.setAttribute)
-
Errors/BindingResult
-
RedirectAttributes( 重定向携带数据)
-
ServletResponse(response)
-
SessionStatus
-
UriComponentsBuilder
-
ServletUriComponentsBuilder
用例:
-
Map<String,Object> map
-
Model model
-
HttpServletRequest request
上面三位都是可以给request域中放数据,用request.getAttribute()
获取
接下来我们看看,Map<String,Object> map
与Model model
用什么参数处理器。
Map<String,Object> map
参数用MapMethodProcessor
处理:
mavContainer.getModel()
如下:
Model model
用ModelMethodProcessor
处理:
return mavContainer.getModel();
这跟MapMethodProcessor
的一致
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-25zCS6cA-1663033047208)(image/20210205010247689.png)]
Model
也是另一种意义的Map
。
接下来看看Map<String,Object> map
与Model model
值是如何做到用request.getAttribute()
获取的。
众所周知,所有的数据都放在 ModelAndView包含要去的页面地址View,还包含Model数据。
先看ModelAndView接下来是如何处理的?
在Debug模式下,view
属为InternalResourceView
类。
exposeModelAsRequestAttributes
方法看出,Map<String,Object> map
,Model model
这两种类型数据可以给request域中放数据,用request.getAttribute()
获取。
2.11 请求处理-【源码分析】-自定义参数绑定原理
封装过程用到ServletModelAttributeMethodProcessor
WebDataBinder 利用它里面的 Converters 将请求数据转成指定的数据类型。再次封装到JavaBean中
在过程当中,用到GenericConversionService:在设置每一个值的时候,找它里面的所有converter那个可以将这个数据类型(request带来参数的字符串)转换到指定的类型
2.12 请求处理-【源码分析】-自定义Converter原理
未来我们可以给WebDataBinder里面放自己的Converter;
下面演示将字符串“啊猫,3”
转换成Pet
对象。
2.13 响应处理-【源码分析】-ReturnValueHandler原理
控制层代码如下:
32、请求处理-【源码分析】-各种类型参数解析原理 - 返回值处理器有讨论ReturnValueHandler。现在直接看看重点:
@ResponseBody
注解,即RequestResponseBodyMethodProcessor
,它实现HandlerMethodReturnValueHandler
接口
2.14 响应处理-【源码分析】-HTTPMessageConverter原理
返回值处理器ReturnValueHandler
原理:
- 返回值处理器判断是否支持这种类型返回值
supportsReturnType
- 返回值处理器调用
handleReturnValue
进行处理 RequestResponseBodyMethodProcessor
可以处理返回值标了@ResponseBody
注解的。- 利用
MessageConverters
进行处理 将数据写为json- 内容协商(浏览器默认会以请求头的方式告诉服务器他能接受什么样的内容类型)
- 服务器最终根据自己自身的能力,决定服务器能生产出什么样内容类型的数据,
- SpringMVC会挨个遍历所有容器底层的
HttpMessageConverter
,看谁能处理?- 得到
MappingJackson2HttpMessageConverter
可以将对象写为json - 利用
MappingJackson2HttpMessageConverter
将对象转为json再写出去。
- 得到
- 利用
HTTPMessageConverter
接口:
HttpMessageConverter
: 看是否支持将 此 Class
类型的对象,转为MediaType
类型的数据。
例子:Person
对象转为JSON,或者 JSON转为Person
,这将用到MappingJackson2HttpMessageConverter
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Evvn3rKN-1663033158301)(image/20210205010509984.png)]
关于MappingJackson2HttpMessageConverter
的实例化请看下节。
[1] 关于HttpMessageConverters的初始化
DispatcherServlet
的初始化时会调用initHandlerAdapters(ApplicationContext context)
上述代码会加载ApplicationContext
的所有HandlerAdapter
,用来处理@RequestMapping
的RequestMappingHandlerAdapter
实现HandlerAdapter
接口,RequestMappingHandlerAdapter
也被实例化。
在构造器中看到一堆HttpMessageConverter
。接着,重点查看AllEncompassingFormHttpMessageConverter
类:
在AllEncompassingFormHttpMessageConverter
类构造器看到MappingJackson2HttpMessageConverter
类的实例化,AllEncompassingFormHttpMessageConverter
包含MappingJackson2HttpMessageConverter
。
ReturnValueHandler
是怎么与MappingJackson2HttpMessageConverter
关联起来?请看下节。
[2] ReturnValueHandler与MappingJackson2HttpMessageConverter关联
再次回顾RequestMappingHandlerAdapter
应用中WebMvcAutoConfiguration
(底层是WebMvcConfigurationSupport
实现)传入更多messageConverters
,其中就包含MappingJackson2HttpMessageConverter
。
2.15 响应处理-【源码分析】-内容协商原理
根据客户端接收能力不同,返回不同媒体类型的数据。
引入XML依赖:
可用Postman软件分别测试返回json和xml:只需要改变请求头中Accept字段(application/json、application/xml)。
Http协议中规定的,Accept字段告诉服务器本客户端可以接收的数据类型。
内容协商原理:
- 判断当前响应头中是否已经有确定的媒体类型
MediaType
。 - 获取客户端(PostMan、浏览器)支持接收的内容类型。(获取客户端Accept请求头字段application/xml)(这一步在下一节有详细介绍)
contentNegotiationManager
内容协商管理器 默认使用基于请求头的策略HeaderContentNegotiationStrategy
确定客户端可以接收的内容类型
- 遍历循环所有当前系统的
MessageConverter
,看谁支持操作这个对象(Person) - 找到支持操作Person的converter,把converter支持的媒体类型统计出来。
- 客户端需要application/xml,服务端有10种MediaType。
- 进行内容协商的最佳匹配媒体类型
- 用 支持 将对象转为 最佳匹配媒体类型 的converter。调用它进行转化 。
2.16 响应处理-【源码分析】-基于请求参数的内容协商原理
上一节内容协商原理的第二步:
获取客户端(PostMan、浏览器)支持接收的内容类型。(获取客户端Accept请求头字段application/xml)
contentNegotiationManager
内容协商管理器 默认使用基于请求头的策略HeaderContentNegotiationStrategy
确定客户端可以接收的内容类型
[1] 开启浏览器参数方式内容协商功能
为了方便内容协商,开启基于请求参数的内容协商功能。
内容协商管理器,就会多了一个ParameterContentNegotiationStrategy
(由Spring容器注入)
然后,浏览器地址输入带format参数的URL:
这样,后端会根据参数format的值,返回对应json或xml格式的数据。
2.17 响应处理-【源码分析】-自定义MessageConverter
实现多协议数据兼容。json、xml、x-guigu(这个是自创的)
-
@ResponseBody
响应数据出去 调用RequestResponseBodyMethodProcessor
处理 -
Processor 处理方法返回值。通过
MessageConverter
处理 -
所有
MessageConverter
合起来可以支持各种媒体类型数据的操作(读、写) -
内容协商找到最终的
messageConverter
SpringMVC的什么功能,一个入口给容器中添加一个 WebMvcConfigurer
用Postman发送/test/person
(请求头Accept:application/x-guigu
),将返回自定义协议数据的写出。
2.18 响应处理-【源码分析】-浏览器与PostMan内容协商完全适配
假设你想基于自定义请求参数的自定义内容协商功能。
换句话,在地址栏输入http://localhost:8080/test/person?format=gg
返回数据,跟http://localhost:8080/test/person
且请求头参数Accept:application/x-guigu
的返回自定义协议数据的一致。
日后开发要注意,有可能我们添加的自定义的功能会覆盖默认很多功能,导致一些默认的功能失效。
3 Web之视图解析
3.1 Thymeleaf初体验
Thymeleafis a modern server-side Java template engine for both
web and standalone environments. Thymeleaf’s main goal is to bring
elegant natural templates to your development workflow — HTML that
can be correctly displayed in browsers and also work as static
prototypes, allowing for stronger collaboration in development teams.
With modules for Spring Framework, a host of integrations with your favourite tools, and the ability to plug in your own
functionality, Thymeleaf is ideal for modern-day HTML5 JVM web
development — although there is much more it can
do.——Link
3.1.1 thymeleaf使用
[1] 引入Starter
自动配置好了thymeleaf
/templates/success.html
:
@和$的区别就是@只是将解析地址解析为字符串,不是真正的动态的。
这个设置后,URL要插入/app
, 如http://localhost:8080/app/hello.html
。
3.1.2 基本语法
[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]特殊操作
- 无操作: _
3.1.3 设置属性值-th:attr
- 设置单个值
- 设置多个值
官方文档 - 5 Setting Attribute Values
3.1.4 迭代
3.1.5 条件运算
3.1.6 属性优先级
Order | Feature | Attributes |
---|---|---|
1 | Fragment inclusion | th:insert th:replace |
2 | Fragment iteration | th:each |
3 | Conditional evaluation | th:if th:unless th:switch th:case |
4 | Local variable definition | th:object th:with |
5 | General attribute modification | th:attr th:attrprepend th:attrappend |
6 | Specific attribute modification | th:value th:href th:src ... |
7 | Text (tag body modification) | th:text th:utext |
8 | Fragment specification | th:fragment |
9 | Fragment removal | th:remove |
官方文档 - 10 Attribute Precedence
3.2 web实验-后台管理系统基本功能
3.2.1 项目创建
使用IDEA的Spring Initializr。
- thymeleaf、
- web-starter、
- devtools、
- lombok
3.2.2 登陆页面
-
/static
放置 css,js等静态资源 -
/templates/login.html
登录页
/templates/main.html
主页
thymeleaf内联写法:
3.2.3 登录控制层
3.2.4 模型
3.2.5 抽取公共页面
- 公共页面
/templates/common.html
- 我们发现要实现跳转的这几个页面都是有共同特点的。比如说侧边栏和顶部。这样如果每一个页面我们都在里面进行修改或者其他事情的话,会导致资源的浪费。所以我们可以将这些页面都有的部分抽取出来,作为一个公共页面,然后使用thymeleaf进行动态引入。
/templates/table/basic_table.html
Difference between th:insert
and th:replace
(and th:include
)
[1]fragment
类似于JSP的tag,在html中文件中,可以将多个地方出现的元素块用fragment包起来使用。
3.2.6 遍历数据与页面bug修改
控制层代码:
页面代码:
3.2.7 视图解析-【源码分析】-视图解析器与视图
视图解析原理流程:
- 目标方法处理的过程中(阅读
DispatcherServlet
源码),所有数据都会被放在ModelAndViewContainer
里面,其中包括数据和视图地址。 - 方法的参数是一个自定义类型对象(从请求参数中确定的),把他重新放在
ModelAndViewContainer
。 - 任何目标方法执行完成以后都会返回
ModelAndView
(数据和视图地址)。 processDispatchResult()
处理派发结果(页面改如何响应)render(mv, request, response);
进行页面渲染逻辑- 根据方法的
String
返回值得到View
对象【定义了页面的渲染逻辑】
- 所有的视图解析器尝试是否能根据当前返回值得到
View
对象 - 得到了
redirect:/main.html --> Thymeleaf new RedirectView()
。 ContentNegotiationViewResolver
里面包含了下面所有的视图解析器,内部还是利用下面所有视图解析器得到视图对象。view.render(mv.getModelInternal(), request, response);
视图对象调用自定义的render进行页面渲染工作。
RedirectView
如何渲染【重定向到一个页面】- 获取目标url地址
response.sendRedirect(encodedURL);
- 根据方法的
视图解析:
- 返回值以 forward:
开始: new InternalResourceView(forwardUrl);
--> 转发request.getRequestDispatcher(path).forward(request, response);
- 返回值以 redirect:
开始: new RedirectView()
--> render就是重定向
- 返回值是普通字符串:new ThymeleafView()
—>
3.2.8 拦截器-登录检查与静态资源放行
-
编写一个拦截器实现
HandlerInterceptor
接口 -
拦截器注册到容器中(实现
WebMvcConfigurer
的addInterceptors()
) -
指定拦截规则(注意,如果是拦截所有,静态资源也会被拦截】
编写一个实现HandlerInterceptor
接口的拦截器:
拦截器注册到容器中 && 指定拦截规则:
[1]拦截器、监听器、过滤器
3.2.9 拦截器-【源码分析】-拦截器的执行时机和原理
- 根据当前请求,找到
HandlerExecutionChain
(可以处理请求的handler以及handler的所有 拦截器) - 先来顺序执行 所有拦截器的
preHandle()
方法。- 如果当前拦截器
preHandle()
返回为true
。则执行下一个拦截器的preHandle()
- 如果当前拦截器返回为
false
。直接倒序执行所有已经执行了的拦截器的afterCompletion();
。
- 如果当前拦截器
- 如果任何一个拦截器返回
false
,直接跳出不执行目标方法。 - 所有拦截器都返回
true
,才执行目标方法。 - 倒序执行所有拦截器的
postHandle()
方法。 - 前面的步骤有任何异常都会直接倒序触发
afterCompletion()
。 - 页面成功渲染完成以后,也会倒序触发
afterCompletion()
。
DispatcherServlet
中涉及到HandlerInterceptor
的地方:
3.2.10 文件上传-单文件与多文件上传的使用
- 页面代码
/static/form/form_layouts.html
- 控制层代码
文件上传相关的配置类:
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.MultipartProperties
文件大小相关配置项:
3.2.11 文件上传-【源码流程】文件上传参数解析器
文件上传相关的自动配置类MultipartAutoConfiguration
有创建文件上传参数解析器StandardServletMultipartResolver
。
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
跳到以下的类
this.argumentResolvers
其中主角类RequestPartMethodArgumentResolver
用来生成
3.2.12 错误处理-SpringBoot默认错误处理机制
Spring Boot官方文档 - Error Handling
默认规则:
-
默认情况下,Spring Boot提供
/error
处理所有错误的映射 -
机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
-
要对其进行自定义,添加
View
解析为error
-
要完全替换默认行为,可以实现
ErrorController
并注册该类型的Bean定义,或添加ErrorAttributes类型的组件
以使用现有机制但替换其内容。 -
/templates/error/
下的4xx,5xx页面会被自动解析
3.2.13 错误处理-【源码分析】底层组件功能分析
ErrorMvcAutoConfiguration
自动配置异常处理规则- 容器中的组件:类型:
DefaultErrorAttributes
-> id:errorAttributes
public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver
DefaultErrorAttributes
:定义错误页面中可以包含数据(异常明细,堆栈信息等)。
- 容器中的组件:类型:
BasicErrorController
--> id:basicErrorController
(json+白页 适配响应) - 处理默认
/error
路径的请求,页面响应new ModelAndView("error", model);
- 容器中有组件
View
->id是error;(响应默认错误页) - 容器中放组件
BeanNameViewResolver
(视图解析器);按照返回的视图名作为组件的id去容器中找View
对象。
- 容器中有组件
- 容器中的组件:类型:
DefaultErrorViewResolver
-> id:conventionErrorViewResolver
- 如果发生异常错误,会以HTTP的状态码 作为视图页地址(viewName),找到真正的页面(主要作用)。
- error/404、5xx.html
- 如果想要返回页面,就会找error视图(
StaticView
默认是一个白页)。
3.2.14 错误处理-【源码流程】异常处理流程
譬如写一个会抛出异常的控制层:
当浏览器发出/hello
请求,DispatcherServlet
的doDispatch()
的mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
将会抛出ArithmeticException
。
系统自带的异常解析器:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sDtv8gfi-1663312186789)(image/20210205011338251.png)]
DefaultErrorAttributes
先来处理异常,它主要功能把异常信息保存到request域,并且返回null。
-
默认没有任何解析器(上图的
HandlerExceptionResolverComposite
)能处理异常,所以最后异常会被抛出。 -
最终底层就会转发
/error
请求。会被底层的BasicErrorController
处理。
3.2.15 错误处理-【源码流程】几种异常处理原理
-
自定义错误页
- error/404.html error/5xx.html;有精确的错误状态码页面就匹配精确,没有就找 4xx.html;如果都没有就触发白页
-
@ControllerAdvice
+@ExceptionHandler
处理全局异常;底层是ExceptionHandlerExceptionResolver
支持的
@ResponseStatus
+自定义异常 ;底层是ResponseStatusExceptionResolver
,把responseStatus注解的信息底层调用response.sendError(statusCode, resolvedReason)
,tomcat发送的/error
-
Spring自家异常如
org.springframework.web.bind.MissingServletRequestParameterException
,DefaultHandlerExceptionResolver
处理Spring自家异常。 -
response.sendError(HttpServletResponse.SC_BAD_REQUEST/*400*/, ex.getMessage());
-
自定义实现
HandlerExceptionResolver
处理异常;可以作为默认的全局异常处理规则
ErrorViewResolver
实现自定义处理异常response.sendError()
,error请求就会转给controller。- 你的异常没有任何人能处理,tomcat底层调用
response.sendError()
,error请求就会转给controller。 basicErrorController
要去的页面地址是ErrorViewResolver
。
3.2.16 原生组件注入-原生注解与Spring方式注入
官方文档 - Servlets, Filters, and listeners
3.2.17 使用原生的注解
最后还要在主启动类添加注解@ServletComponentScan
3.2.18 Spring方式注入
ServletRegistrationBean
, FilterRegistrationBean
, and ServletListenerRegistrationBean
3.2.19 原生组件注入-【源码分析】DispatcherServlet注入原理
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
配置类
DispatcherServlet
默认映射的是 /
路径,可以通过在配置文件修改spring.mvc.servlet.path=/mvc
。
3.2.20 嵌入式Servlet容器-【源码分析】切换web服务器与定制化
-
默认支持的WebServer
Tomcat
,Jetty
, orUndertow
。ServletWebServerApplicationContext
容器启动寻找ServletWebServerFactory
并引导创建服务器。
-
原理
- SpringBoot应用启动发现当前是Web应用,web场景包-导入tomcat。
- web应用会创建一个web版的IOC容器
ServletWebServerApplicationContext
。 ServletWebServerApplicationContext
启动的时候寻找ServletWebServerFactory
(Servlet 的web服务器工厂——>Servlet 的web服务器)。- SpringBoot底层默认有很多的WebServer工厂(
ServletWebServerFactoryConfiguration
内创建Bean),如:TomcatServletWebServerFactory
JettyServletWebServerFactory
UndertowServletWebServerFactory
- 底层直接会有一个自动配置类
ServletWebServerFactoryAutoConfiguration
。 ServletWebServerFactoryAutoConfiguration
导入了ServletWebServerFactoryConfiguration
(配置类)。ServletWebServerFactoryConfiguration
根据动态判断系统中到底导入了那个Web服务器的包。(默认是web-starter导入tomcat包),容器中就有TomcatServletWebServerFactory
TomcatServletWebServerFactory
创建出Tomcat服务器并启动;TomcatWebServer
的构造器拥有初始化方法initialize——this.tomcat.start();
- 内嵌服务器,与以前手动把启动服务器相比,改成现在使用代码启动(tomcat核心jar包存在)。
Spring Boot默认使用Tomcat服务器,若需更改其他服务器,则修改工程pom.xml:
3.2.21 定制Servlet容器
-
实现
WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
-
- 把配置文件的值和
ServletWebServerFactory
进行绑定
- 把配置文件的值和
-
修改配置文件
server.xxx
-
直接自定义
ConfigurableServletWebServerFactory
xxxxxCustomizer
:定制化器,可以改变xxxx的默认规则
3.2.22 定制化原理-SpringBoot定制化组件的几种方式(小结)
[1] 定制化的常见方式
-
修改配置文件
-
xxxxxCustomizer
-
编写自定义的配置类
xxxConfiguration
+@Bean
替换、增加容器中默认组件,视图解析器 -
Web应用 编写一个配置类实现
WebMvcConfigurer
即可定制化web功能 +@Bean
给容器中再扩展一些组件
@EnableWebMvc
+WebMvcConfigurer
—@Bean
可以全面接管SpringMVC,所有规则全部自己重新配置; 实现定制和扩展功能(高级功能,初学者退避三舍)。- 原理:
WebMvcAutoConfiguration
默认的SpringMVC的自动配置功能类,如静态资源、欢迎页等。- 一旦使用
@EnableWebMvc
,会@Import(DelegatingWebMvcConfiguration.class)
。 DelegatingWebMvcConfiguration
的作用,只保证SpringMVC最基本的使用- 把所有系统中的
WebMvcConfigurer
拿过来,所有功能的定制都是这些WebMvcConfigurer
合起来一起生效。 - 自动配置了一些非常底层的组件,如
RequestMappingHandlerMapping
,这些组件依赖的组件都是从容器中获取如。 public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
。
- 把所有系统中的
WebMvcAutoConfiguration
里面的配置要能生效必须@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
。- @EnableWebMvc 导致了WebMvcAutoConfiguration 没有生效。
- 原理:
[2] 原理分析套路
场景starter - xxxxAutoConfiguration
- 导入xxx组件 - 绑定xxxProperties
- 绑定配置文件项。
3.2.23 数据访问-数据库场景的自动配置分析与整合测试
[1] 导入JDBC场景
接着导入数据库驱动包(MySQL为例)。
[2] 相关数据源配置类
-
DataSourceAutoConfiguration
: 数据源的自动配置。- 修改数据源相关的配置:
spring.datasource
。 - 数据库连接池的配置,是自己容器中没有DataSource才自动配置的。
- 底层配置好的连接池是:
HikariDataSource
。
- 修改数据源相关的配置:
-
DataSourceTransactionManagerAutoConfiguration
: 事务管理器的自动配置。 -
JdbcTemplateAutoConfiguration
:JdbcTemplate
的自动配置,可以来对数据库进行CRUD。- 可以修改前缀为
spring.jdbc
的配置项来修改JdbcTemplate
。 @Bean @Primary JdbcTemplate
:Spring容器中有这个JdbcTemplate
组件,使用@Autowired
。
- 可以修改前缀为
-
JndiDataSourceAutoConfiguration
: JNDI的自动配置。 -
XADataSourceAutoConfiguration
: 分布式事务相关的。
[3] 修改配置项
[4] 单元测试数据源
3.2.24 数据访问-自定义方式整合druid数据源
[1] Druid是什么?
它是数据库连接池,它能够提供强大的监控和扩展功能。
Spring Boot整合第三方技术的两种方式:
-
自定义
-
找starter场景
[2] 自定义方式
添加依赖:
配置Druid数据源:
配置Druid的监控页功能:
-
Druid内置提供了一个
StatViewServlet
用于展示Druid的统计信息。官方文档 - 配置_StatViewServlet配置。这个StatViewServlet
的用途包括:- 提供监控信息展示的html页面
- 提供监控信息的JSON API
-
Druid内置提供一个
StatFilter
,用于统计监控信息。官方文档 - 配置_StatFilter -
WebStatFilter
用于采集web-jdbc关联监控的数据,如SQL监控、URI监控。官方文档 - 配置_配置WebStatFilter -
Druid提供了
WallFilter
,它是基于SQL语义分析来实现防御SQL注入攻击的。官方文档 - 配置 wallfilter
3.2.25 注意
对于查看错误日志报告,一般都是查看最后一段,这个一般是最基本的错误。
本次springboot整合mybatis启动中主要是因为
解决办法:把configuration注解掉。
3.2.26 数据访问-druid数据源starter整合方式
官方文档 - Druid Spring Boot Starter
引入依赖:
分析自动配置:
- 扩展配置项
spring.datasource.druid
- 自动配置类
DruidDataSourceAutoConfigure
DruidSpringAopConfiguration.class
, 监控SpringBean的;配置项:spring.datasource.druid.aop-patterns
DruidStatViewServletConfiguration.class
, 监控页的配置。spring.datasource.druid.stat-view-servlet
默认开启。DruidWebStatFilterConfiguration.class
,web监控配置。spring.datasource.druid.web-stat-filter
默认开启。DruidFilterConfiguration.class
所有Druid的filter的配置:
配置示例:
3.2.27 数据访问-整合MyBatis-配置版
starter的命名方式:
- SpringBoot官方的Starter:
spring-boot-starter-*
- 第三方的:
*-spring-boot-starter
引入依赖:
配置模式:
-
全局配置文件
-
SqlSessionFactory
:自动配置好了 -
SqlSession
:自动配置了SqlSessionTemplate
组合了SqlSession
-
@Import(AutoConfiguredMapperScannerRegistrar.class)
-
Mapper
: 只要我们写的操作MyBatis的接口标准了@Mapper
就会被自动扫描进来
配置文件:
mybatis-config.xml:
Mapper接口:
POJO:
DB:
Controller and Service:
配置private Configuration configuration;
也就是配置mybatis.configuration
相关的,就是相当于改mybatis全局配置文件中的值。(也就是说配置了mybatis.configuration
,就不需配置mybatis全局配置文件了)
小结
- 导入MyBatis官方Starter。
- 编写Mapper接口,需
@Mapper
注解。 - 编写SQL映射文件并绑定Mapper接口。
- 在
application.yaml
中指定Mapper配置文件的所处位置,以及指定全局配置文件的信息 (建议:配置在mybatis.configuration
)。
3.2.28 数据访问-整合MyBatis-注解配置混合版
你可以通过Spring Initializr添加MyBatis的Starer。
注解与配置混合搭配,干活不累:
-
简单DAO方法就写在注解上。复杂的就写在配置文件里。
-
使用
@MapperScan("com.lun.boot.mapper")
简化,Mapper接口就可以不用标注@Mapper
注解。
3.2.29 数据访问-整合MyBatisPlus操作数据库
MyBatisPlus是什么
MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
添加依赖:
-
MybatisPlusAutoConfiguration
配置类,MybatisPlusProperties
配置项绑定。 -
SqlSessionFactory
自动配置好,底层是容器中默认的数据源。 -
mapperLocations
自动配置好的,有默认值classpath*:/mapper/**/*.xml
,这表示任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件放在 mapper下。 -
容器中也自动配置好了
SqlSessionTemplate
。 -
@Mapper
标注的接口也会被自动扫描,建议直接@MapperScan("com.lun.boot.mapper")
批量扫描。 -
MyBatisPlus优点之一:只需要我们的Mapper继承MyBatisPlus的
BaseMapper
就可以拥有CRUD能力,减轻开发工作。
3.2.30 数据访问-CRUD实验-数据列表展示
使用MyBatis Plus提供的IService
,ServiceImpl
,减轻Service层开发工作。
与下一节联合在一起
数据访问-CRUD实验-分页数据展示
与下一节联合在一起
3.2.31 数据访问-CRUD实验-删除用户完成
添加分页插件:
#numbers
表示methods for formatting numeric objects.link
3.2.32 数据访问-准备阿里云Redis环境
添加依赖:
RedisAutoConfiguration
自动配置类,RedisProperties 属性类 --> spring.redis.xxx是对redis的配置。- 连接工厂
LettuceConnectionConfiguration
、JedisConnectionConfiguration
是准备好的。 - 自动注入了
RedisTemplate<Object, Object>
,xxxTemplate
。 - 自动注入了
StringRedisTemplate
,key,value都是String - 底层只要我们使用
StringRedisTemplate
、RedisTemplate
就可以操作Redis。
外网Redis环境搭建:
-
阿里云按量付费Redis,其中选择经典网络。
-
申请Redis的公网连接地址。
-
修改白名单,允许
0.0.0.0/0
访问。
3.2.33 数据访问-Redis操作与统计小实验
相关Redis配置:
测试Redis连接:
Redis Desktop Manager:可视化Redis管理软件。
URL统计拦截器:
注册URL统计拦截器:
Filter、Interceptor 几乎拥有相同的功能?
- Filter是Servlet定义的原生组件,它的好处是脱离Spring应用也能使用。
- Interceptor是Spring定义的接口,可以使用Spring的自动装配等功能。
调用Redis内的统计数据:
后记
未完待续,下一篇章
__EOF__

本文链接:https://www.cnblogs.com/hxld/p/16829427.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律