《疯狂Spring Boot讲义》是2021年电子工业出版社出版的图书,作者是李刚
《疯狂Spring Boot终极讲义》不是一本介绍类似于@PathVariable、@MatrixVariable、@RequestBody、@ResponseBody这些基础注解的图书,它是真正讲解Spring Boot的图书。Spring Boot的核心是什么?它的核心就是自动配置,以及以自动配置为基础与大量第三方后端技术进行整合。因此学习Spring Boot应该重点关注的就是它为整合各种框架所提供的自动配置,包括Spring Boot如何整合各种前端框架,如Spring MVC、Spring WebFlux;Spring Boot如何整合各种持久层技术,如Spring Data、MyBatis、Hibernate/JPA、R2DBC、jOOQ等;Spring Boot如何整合NoSQL技术,如Redis、MongoDB、Neo4j、Cassandra、Solr、Elasticsearch等;Spring Boot如何整合各种消息组件,如ActiveMQ、Artemis、RabbitMQ、Kafka等;Spring Boot如何整合各种缓存机制,如JCache、EhCache、Redis、Hazelcast等;Spring Boot如何整合各种安全框架,如Spring Security、Shiro等,这些都只是Spring Boot整合的典型内容。本书的作用就是带你彻底掌握Spring Boot官方手册中所整合的各种技术,而且本书会讲清楚Spring Boot和Spring框架的关系,带着你揭开Spring Boot的核心:自动配置的面纱,领着你剖析Spring Boot自动配置的源代码实现,然后以此为基础,详细讲解Spring Boot如何整合各种Java后端技术。在掌握了本书知识之后,你不仅能轻松看懂Spring Boot官方手册(其实无须再看了),而且真正掌握了Spring Boot的大成,并通过Spring Boot的整合触类旁通地掌握各种Java后端技术。本书提供了读者答疑交流群,读者可通过扫描本书封面上的二维码,按照指引加入读者答疑交流群。

技术示范:高并发请求提供及时响应,对秒杀请求的瞬时高并发进行削峰限流
项目背景
- 电商在特殊时间节点做促销活动,参与商品的价格实惠,用户特意等到活动期间购买
 - 从而很容易引起瞬时的高并发请求的峰值情况
 - 通常通过RabbitMQ消息组件进行削峰,即限制、延迟处理,避免服务器崩溃。
 
系统架构
|   MVC  |   Spring MVC  |   用户请求的处理与转发; 包括系统的超链接与表单提交  |   拦截器的权限控制  | 
|   底层持久层 DAO层  |   MyBatis  |   简化,优化与封装  |   SQL Mapping框架 Mapper接口  | 
|   NoSQL 分布式Session  |   Redis  |   数据缓存、页面缓存  | |
|   消息组件  |   RabbitMQ  |   秒杀限流  | |
|   业务逻辑层  |   Spring Boot  |   整合与自动配置;业务逻辑组件  |   依赖注入;面向接口; IoC;声明式事务框架  | 
|   表现层  |   Thymeleaf  |   收集用户请求数据; 业务数据表示  | |
|   Bootstrap  |   简单美化  | ||
|   jQuery  |   JS工具库动态更新页面  | 
功能模块
- 主要是用户模块和秒杀模块
 - 业务逻辑组件为门面封装且依赖Mapper组件
 
|   Mapper对象组件| 4  |   UserMapper  |   user_inf  | 
|   MiaoshaItemMapper  |   item_inf、miaoshao_inf  | |
|   OrderMapper  |   order_inf  | |
|   MiaoshaOrderMapper  |   order_inf、miaosha_order  | |
|   业务逻辑组件| 2  |   UserService  |   用户登录、用户信息查看  | 
|   MiaoshaService  |   商品查看、商品秒杀  | |
|   消息组件| 2  |   MiaoshaSender  |   向RabbitMQ消息队列发送消息  | 
|   MiaoshaReceiver  |   接受RabbitMQ消息队列中的消息  | |
|   操作Redis组件| 1  |   FkRedisUtil  | 
加工逻辑
项目搭建
- 通过Spring Boot整合框架的自动配置,只需要在pom.xml中添加对应依赖库
 
其他依赖库
|   Apache Commons Pool2连接池  |   连接Redis  | 
|   Common Lang 3  |   StringUtils、ArrayUtils、ClassUtils、RegExUtils工具类  | 
|   Common Codec  |   编码、解码算法,如MD5加密算法  | 
领域对象层
设计领域对象
- MyBatis的SQL Mapping进行持久化操作,从而保证面向对象方式开发
 
|   user_inf  |   nickname not null;加盐加密  | |
|   item_inf  |   主键自增  |   商品名称、商品描述  | 
|   miaosha_item  |   主键自增  |   基本信息; 秒杀价、库存、开始结束时间  | 
|   order_inf  |   主键自增  |   订单用户、订单价格、下单时间  | 
|   miaosh_order  |   主键自增; unique key(user_id, item_id)唯一约束  |   用户ID、订单ID、商品ID  | 
创建领域对象类
- MyBatis是结果集映射框架
 - 只需要定义数据列的类实例变量以及setter、getter方法
 
Mapper(DAO)层
- MyBatis只需要通过XML文件定义Mapper接口的相关SQL语句就开发完成Mapper组件。
 
实现Mapper组件
- Mapper接口声明Mapper组件提供的持久化对象操作的CRUD方法
 - 可能随着业务逻辑的需求而增加
 
|   UserMapper接口  |   根据user_id查询user_inf; 更新user_inf  |   @Select(“SQL语句”) @Update(“SQL语句”)  | 
|   MiaoshaItemMapper接口  |   更新库存 查询所有秒杀商品 查询指定秒杀商品  |   @Result(参数) List<MiaoshaItem> @Param  | 
|   OrderMapper接口  |   插入新纪录 获取订单  |   @Insert(“SQL语句”) @Option(参数)  | 
|   MiaoshaOrderMapper接口  |   获取秒杀订单 插入秒杀订单  | 
部署Mapper组件
Spring Boot自动配置数据源、SqlSessionFactory基础组件,部署Mapper成容器的Bean
|   spring.datasource  |   .driver-class-name  |   =com.mysql.cj.jdbc.Driver  | 
|   .url  |   =mysql://localhost:3306/...  | |
|   .username  | ||
|   .password  | 
分布式Session及用户登录的实现
权限管理等采用分布式Session,高并发秒杀系统通常都是分布式应用,基于Redis实现
实现Redis组件
- 添加Spring Boot Data Redis,提供自动配置RedisConnectionFactory、StringRedisTmplate
 - 注入其他组件即可
 
|   spring.redis  |   host  | ||
|   port  | |||
|   database  | |||
|   password  | |||
|   lettuce.pool  |   .maxActive  | ||
|   .maxIdle  |   空闲连接数  | ||
|   .minIdle  | 
- 工具类对RedisTemplate封装
 - 方便操作系统中的key-value对
 - 包括添加key-value对、根据key获取对应的value、根据key删除指定key-value 对、判断指定的key是否存在等
 
|   FkRedisUtil  |   get:获取相应的value  |   RedisTemplate: opsForValue: get  | 
|   set:添加key-value对  |   opsForValue: set: Duration.ofSeconds  | |
|   exists:key是否存在  |   RedisTemplate: hasKey;  | |
|   delete:根据key删除  |   RedisTemplate: delete  | |
|   incr  |   RedisTemplate: opsForValue: increment  | |
|   decr  |   RedisTemplate: opsForValue: decrement  | |
|   beanTostring  |   ObjectMapper.writeValueAsString;  | |
|   stringToBean  |   ObjectMapper.readValue  | 
- 控制前缀部分,避免重复
 - 控制过期时间
 
|   KeyPrefix  |   定义prefix以及过期时间  | 
便于KeyPrefix提供实现类,而作为基类
|   AbstractPrefix  |   设置过期时间 定义:类名:prefix  | 
分布式Session的实现
- Session ID发送浏览器,以Cookie保存[UUID]
 - 服务器端用Redis保存key-value信息,以客户端的Session ID为key
 - 对象:分布式Session
 
- 为了实现流程,定义操作Cookie工具类
 - getSessionId工具方法就是分布式Session实现机制的第1步:通过Cookie来读取Session ID;如果读不到有效的Session ID,系统会生成一个随机的UUID作为Session ID,并将该Session ID 以Cookie的形式写入浏览器,交给浏览器保存。
 
|   key  |   value  | |
|   Cookie  |   “token”  |   UUID  | 
|   Redis  |   prefix+UUID  |   Session信息  | 
|   CookieUtil  |   addSessionID:以Cookie写入  |   HttpServletResponse:addCookie Cookie: setMaxAge、setPath  | 
|   getCookieValue:读取指定  |   HttpServletRequest: getCookies() Cookie: getName、getValue  | |
|   getSessionId:读取,否则创建  |   对getCookieValue进一步封装  | 
通过Redis缓存实现分布式Session
|   UserController  |   addSession: 分别保存  | |
|   getByToken:延长有效期、读取  | 
只要任意控制器访问系统,拦截器就会向氛围中的浏览器写入Cookie,从而保存SessionID
|   AccessInterceptor  |   preHandle:访问写入、保存 拦截所有控制器的处理方法  |   HandlerInterceptor: preHandle  | 
|   UserKey  |   key前缀以及有效时间  | 
用户登录的实现
getLoginVerifyCode符合分布式的Session流程
|   UserController  |   toLogin  | |
|   getLoginVerifyCode:验证码  |   @GetMappring(method) HttpServletResponse:getOutputStream  | |
|   proLogin  |