文章目录
- 前言
- 完成任务
-
- [1. elasticSearch 搜索](#1. elasticSearch 搜索)
-
- [1.1 安装 es](#1.1 安装 es)
- [1.2 es 初始化](#1.2 es 初始化)
- [1.3 es 新增修改](#1.3 es 新增修改)
- [1.4 es 搜索](#1.4 es 搜索)
- [2. 热门视频、更新上次播放时间](#2. 热门视频、更新上次播放时间)
- [3. AOP 校验](#3. AOP 校验)
-
- [3.1 AOP 登录校验](#3.1 AOP 登录校验)
- [3.2 AOP 消息记录](#3.2 AOP 消息记录)
- [4. 消息管理](#4. 消息管理)
- [5. 播放历史](#5. 播放历史)
- 总结

前言
本项目非原创,我只是个小小白,跟随 b 站脚步,找到老罗的这个项目,视频来源于:
高仿B站(单服务版) springboot项目实战 easylive
本人不分享项目源码,支持项目付费!!!
完成任务
1. elasticSearch 搜索
1.1 安装 es
因为是第一次接触 elasticSearch,所以安装和基本的常用操作都是跟着老罗简单实践了一下。后面准备再去学一下 es。
- 安装并启动elasticsearch
双击 es 的 bin 目录下的 .bat 文件,启动 es:
浏览器输入http://localhost:9200/
,成功启动后,会显示:
- 启动 kibanna
同样点击 kibanna 的 bin 目录下的 .bat 文件,启动 kibanna:
浏览器输入:http://localhost:5601/app/home#/,启动成功后,会显示:
点击 explore on my own,
1.2 es 初始化
pom.xml 文件中导入 es 依赖:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
创建一个 EsSearchComponent 的组件,主要用于与Elasticsearch进行交互,执行视频信息的索引创建、文档增删改查以及用户信息的关联查询操作:
在 AppConfig 中加入 es 相关属性。
es 创建索引要在服务启动时调用,创建一个 InitRun 的类, 在 Spring Boot 应用程序启动时执行 es 初始化操作:
EsSearchComponent 组件类的中创建索引:
request.settings
设置索引的分析器(analyzer),用于分析文本并将其转换为倒排索引的方式。定义一个名为comma的分析器,使用正则表达式按逗号分隔文本。request.mapping
:设置索引的映射(mapping),映射定义了索引中每个字段的类型及其他设置。videoName字段,使用了 ik_max_word 分析器,这是一种中文分词器。tags字段,使用了前面定义的comma分析器。index
: false属性表示该字段不会被索引,因此在查询时无法直接使用这些字段进行检索。
EsConfiguration 配置类:用于在Spring应用中配置和销毁Elasticsearch的客户端。
- 通过继承 AbstractElasticsearchConfiguration 类来简化配置过程,实现了 DisposableBean 接口,确保在Spring容器销毁时能够正确地关闭Elasticsearch客户端,释放资源。
启动后,可以在 kibanna 启动后显示:
1.3 es 新增修改
上面操作完成后,就相当于已经创建了表,现在就是需要往 es 中写入内容。
es 与 MySQL 不一样,es 是以文档形式存储,一条记录就是一个文档。
保存文档:
VideoInfoPostServiceImpl 审核视频时,保存视频信息到 es:
更新文档:
保存文档时先判断索引是否已经存在,如果存在,那就是对其进行更新操作:
通过反射获取VideoInfo对象的所有字段值,并构建一个更新请求来更新Elasticsearch中的对应文档。该方法确保不会更新 lastUpdateTime 和 createTime 字段,并且只更新非空的字段值。(过滤掉空值字段)
如果直接使用 videoInfo 对象进行更新,传入的 videoInfo 是那些更新的字段的值,那些没有更新的字段是 null,直接传入,就把 es 中原本不为 null 的字段也更新为 null 了,不合适。
更新数量:
在前面更新弹幕数量的时候,就需要更新 es 中的弹幕数量:
因为有很多数量需要更新,所以用一个枚举来表示修改的数量类型:
更新收藏数量:
删除视频:
1.4 es 搜索
搜索出来的视频,会对搜索的关键词进行高亮的显示。
对从 es 中查询到的视频数据,要将 Json 结果转为 videoInfo ,并将 videoIndo 的视频名设置为关键词。
根据上面获取到的用户 id 列表,从数据库中查询用户信息,并将用户昵称加到 videoIndoList 中的用户中。
controller 层调用该搜索方法:
获取推荐视频列表:
不需要高亮显示,传递参数设置为 false。
获取搜索热词:
点击搜索时,会显示前 10 个搜索热词:
既然要获取,那就要先存储搜索热词,在搜索时,把搜索词存储在 Redis 中,通过 Zset 存储:
controller 层:
2. 热门视频、更新上次播放时间
页面上点击 "热门":
会跳转显示过去 24 小时的热门播放视频:
controller 层:查询过去 24 小时内播放的视频,按照播放量倒序排序
播放的时候,要把更新播放时间、视频播放数量放到消息队列中。因为点击播放的时候,有很多事情需要做,把它放到消息队列中,通过消息队列去完成。避免播放量大时,阻塞线程。
在获取视频资源的时候完成:
为什么是从 Cookie 中获取用户信息,而不是从 token 中直接获取 ?
播放器发送的请求,无法携带 head 头,但是可以携带 Cookie,所以是从 Cookie 中获取用户信息。
将播放的视频信息放到 Redis 消息队列中:
消费 Redis 消息队列中的视频播放:
更新视频播放数量时,就需要更新视频最近的播放时间:
3. AOP 校验
3.1 AOP 登录校验
先自定义一个拦截器的注解:
@Target
:指定自定义注解可以应用的目标元素类型@Retention
:指定注解的保留策略,即注解在哪个级别保留
在用户操作行为,像点赞、收藏、投币等都需要校验登录。
评论相关的也需要校验登录:
创作中心 UCenterInteractController 中,所有的方法都需要校验登录。
发布视频 UCenterVideoPostController 中,所有方法都需要登录...
就是只有登录后才能访问的方法,都需要校验登录。
定义切面:
- 定义切面 ,就是创建一个类,类上方加上
@Aspect
注解,交给 Spring 管理。 - 定义切点 ,事件通知类型(前置、后置、环绕、返回、异常)。登录校验需要前置通知
@Before
,通过上面定义的 GlobalInterceptor 注解去切。 - 通过反射获取方法,通过方法拿到注解。
- 如果获取到的注解有登录校验的值 checkLogin(),就需要校验登录。
3.2 AOP 消息记录
用户点赞、收藏、投币;评论;审核这些,都是会弹出消息的。
使用 AOP 来进行消息记录。上面的校验登录的注解只在 web 模块(客户端)使用,所以把它写在客户端;而消息的话,是管理端和客户端都需要使用,所以放在 common 模块。
自定义消息记录的注解:
消息有很多类型:
将这个自定义的注解加在需要记录的地方
- userAction 中用户操作行为,需要加上消息记录注解:
- 发布评论,需要加上:
- 管理端审核视频,也需要消息记录:
定义切面、切入点:
@Around
:定义环绕通知。这个通知会在所有带有@RecordUserMessage注解的方法前后执行。- 成功获取到自定义的消息注解后,就可以记录消息。
记录消息:
service 层 saveUserMessage() 方法:
- A 给 B 发送了一个评论,B 又给 A 返回一个评论 replyComment,根据 replyCommentId 可以获取 A 发送给 B 的评论 commentInfo。那么对于 B 回复的评论 replyComment ,它的接收者应该是 A。
用户消息传递的 Dto 类:
4. 消息管理
上面已经使用 AOP 记录消息的了,那么对于记录到的消息,如果新收到未读的消息,那就要出现红色的气泡点,还有其它对于消息的管理。
获取未读消息数量:
分组获取未读消息数量:
消息分组类型及数量 Dto

消息标记已读:
获取消息列表:
要通过连表查询。
删除消息:
注意:当前登录用户只能删除自己的收到的 message。
5. 播放历史
记录播放历史:
前面在使用消息队列来处理视频播放的时候,还需要记录视频播放历史:
加载历史记录:
加载视频播放历史,就需要关联视频表,一同查询:
清空播放历史:
删除播放历史:
这里是只删除一个,上面的清空是全都删除
总结
es 是第一次接触,有些地方不是很看得懂,下来还需要再补。
AOP 实现拦截器的过程更进一步理解了。
mapper.xml 文件中的一些 sql 语句还需要多看,多理解。