工作实战之拦截器模式
目录
前言
一、结构中包含的角色
二、拦截器使用
1.拦截器角色
a.自定义拦截器UserValidateInterceptor,UserUpdateInterceptor,UserEditNameInterceptor
b.拦截器配置者UserInterceptorChainConfigure,任意组装拦截器顺序
c.拦截器管理者UserInterceptorChainManager
2.运行结果展示
a.使用代码
三、拦截器调用解说
1.项目启动,初始化bean
2.方法执行
四、代码下载
总结
前言
拦截过滤器模式,简称拦截器模式,是责任链模式的一种衍生模式。用于对业务程序做一些预处理/后处理
一、结构中包含的角色
- Interceptor(抽象处理者)
- InterceptorChain(责任链)
- InterceptorChainBuilder(责任链建造者)
- AbstractInterceptorChainManager(链条管理者)
- InterceptorChainConfigure(链条配置者)
二、拦截器使用
1.拦截器角色

a.自定义拦截器UserValidateInterceptor,UserUpdateInterceptor,UserEditNameInterceptor
/*** 校验用户* @author liangxi.zeng*/
@Component
public class UserValidateInterceptor implements Interceptor<User> {/*** 拦截方法** @param user*/@Overridepublic void interceptor(User user) {if(user.getAge() != 10) {throw new CommonException("年龄不对");}System.out.println("校验用户"+user);}
}
b.拦截器配置者UserInterceptorChainConfigure,任意组装拦截器顺序
@Component
public class UserInterceptorChainConfigureimplements InterceptorChainConfigure<User,InterceptorChainBuilder<User>> {/*** 拦截器链配置** @param interceptorChainBuilder 拦截器链构造器*/@Overridepublic void configure(InterceptorChainBuilder<User> interceptorChainBuilder) {interceptorChainBuilder.pre().addInterceptor(UserValidateInterceptor.class).post().addInterceptor(UserUpdateInterceptor.class).addInterceptor(UserEditNameInterceptor.class);}
}
c.拦截器管理者UserInterceptorChainManager
/*** @author liangxi.zeng* 拦截器链管理类*/
@Component
public class UserInterceptorChainManager
extends AbstractInterceptorChainManager<User> {public UserInterceptorChainManager(List<Interceptor<User>> interceptorList,List<InterceptorChainConfigure<User, InterceptorChainBuilder<User>>> configureList) {super(interceptorList, configureList);}
}
2.运行结果展示
a.使用代码
/*** @author liangxi.zeng*/
@RestController
@RequestMapping("/demo")
public class DemoController {@Autowiredprivate UserInterceptorChainManager userInterceptorChainManager;@Autowiredprivate UserService userService;@RequestMapping("/user")public String user() {User user = new User();user.setId("111");user.setName("liangxi");user.setAge(10);userInterceptorChainManager.doInterceptor(user,(u) -> {// 内部创建用户userService.save(user);});return "success";}}

三、拦截器调用解说
1.项目启动,初始化bean
a.初始化责任链管理者UserInterceptorChainManager,调用父类AbstractInterceptorChainManager方法initInterceptorChain,通过责任链建造者初始化责任链
public AbstractInterceptorChainManager(List<Interceptor<T>> interceptorList,List<InterceptorChainConfigure<T, InterceptorChainBuilder<T>>> configureList) {interceptorChain = initInterceptorChain(interceptorList, configureList);LOGGER.info("Register {} InterceptorChain, names are [{}]",interceptorList);}private InterceptorChain<T> initInterceptorChain(List<Interceptor<T>> interceptorList,List<InterceptorChainConfigure<T, InterceptorChainBuilder<T>>> configureList) {if (CollectionUtils.isEmpty(interceptorList)) {throw new IllegalArgumentException("Interceptors is empty.");}if (CollectionUtils.isEmpty(configureList)) {throw new IllegalArgumentException("Interceptor configurers is empty.");}InterceptorChainBuilder<T> builder = new InterceptorChainBuilder<>(interceptorList);configureList.sort(AnnotationAwareOrderComparator.INSTANCE);configureList.forEach(configurer -> {configurer.configure(builder);});return builder.performBuild();}
b.责任链建造者,完成对业务方法前后逻辑的织入
public InterceptorChain performBuild() {List<Interceptor<T>> preInterceptors = filterInterceptor(preInterceptorList);List<Interceptor<T>> postInterceptors = filterInterceptor(postInterceptorList);if (preInterceptors.isEmpty() && postInterceptors.isEmpty()) {throw new IllegalStateException("Registered Pre-Interceptors and Post-Interceptors is empty.");}Consumer<T> preConsumer = (T t) -> {};Consumer<T> postConsumer = (T t) -> {};if (!preInterceptors.isEmpty()) {preConsumer = (T obj) -> {for (Interceptor<T> item : preInterceptors) {item.interceptor(obj);}};}if (!postInterceptors.isEmpty()) {postConsumer = (T obj) -> {for (Interceptor<T> item : postInterceptors) {item.interceptor(obj);}};}return new InterceptorChain(preConsumer,postConsumer);}
2.方法执行
a.从userInterceptorChainManager.doInterceptor 到 interceptorChain.doExecute(target, operation);下面代码,完成代码逻辑
/*** 拦截器调用入口,将核心操作封装成 Consumer 对象传入。** @param target The target to handle.* @param operation The core operation to intercept.*/public final void doExecute(T target, Operation<T> operation) {preConsumer.accept(target);if (operation != null) {operation.execute(target);}postConsumer.accept(target);}
四、代码下载
设计模式可运行代码
https://gitee.com/zenglx/design-pattern.git
总结
前后端请求,可以用现成的filter和spring的Interceptor解决,业务自己的拦截器链模式,可以解决繁琐业务重复代码的问题
相关文章:
工作实战之拦截器模式
目录 前言 一、结构中包含的角色 二、拦截器使用 1.拦截器角色 a.自定义拦截器UserValidateInterceptor,UserUpdateInterceptor,UserEditNameInterceptor b.拦截器配置者UserInterceptorChainConfigure,任意组装拦截器顺序 c.拦截器管理者…...
某美颜app sig参数分析
之前转载过该app的文章,今天翻版重新整理下,版本号:576O5Zu56eA56eAYXBwIHY5MDgw (base64 解码)。 上来先抓个包: jadx搜索关键词 "sigTime",然后定位到这里 看这行代码 cVar.addForm(INoCaptchaComponent.sig, genera…...
Linux - Linux系统优化思路
文章目录影响Linux性能的因素CPU内存磁盘I/O性能网络宽带操作系统相关资源系统安装优化内核参数优化文件系统优化应用程序软件资源系统性能分析工具vmstat命令iostat命令sar命令系统性能分析标准小结影响Linux性能的因素 CPU CPU是操作系统稳定运行的根本,CPU的速…...
2.Elasticsearch入门
2.Elasticsearch入门[toc]1.Elasticsearch简介Elasticsearch是用Java开发并且是当前最流行的开源的企业级搜索引擎。 能够达到实时搜索,稳定,可靠,快速,安装使用方便。客户端支持Java、.NET(C#)、PHP、Pyth…...
RK3399平台开发系列讲解(应用开发篇)断言的使用
🚀返回专栏总目录 文章目录 一、什么是断言二、静态断言三、运行时断言沉淀、分享、成长,让自己和他人都能有所收获!😄 📢断言为我们提供了一种可以静态或动态地检查程序在目标平台上整体状态的能力,与它相关的接口由头文件 assert.h 提供。 一、什么是断言 在编程中…...
云原生系列之使用prometheus监控nginx
前言 大家好,又见面了,我是沐风晓月,本文主要讲解云原生系列之使用prometheus监控nginx 文章收录到 csdn 我是沐风晓月的博客【prometheus监控系列】专栏,此专栏是沐风晓月对云原生prometheus的的总结,希望能够加深自…...
第六届省赛——8移动距离(总结规律)
题目:X星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为1,2,3...当排满一行时,从下一行相邻的楼往反方向排号。比如:当小区排号宽度为6时,开始情形如下:1 2 3 4 5 612 11 10 9 8 713 14 1…...
C++vector 简单实现
一。概述 vector是我们经常用的一个容器,其本质是一个线性数组。通过对动态内存的管理,增删改查数据,达到方便使用的目的。 作为一个线性表,控制元素个数,容量,开始位置的指针分别是: start …...
通用缓存存储设计实践
目录介绍 01.整体概述说明 1.1 项目背景介绍1.2 遇到问题记录1.3 基础概念介绍1.4 设计目标1.5 产生收益分析 02.市面存储方案 2.1 缓存存储有哪些2.2 缓存策略有哪些2.3 常见存储方案2.4 市面存储方案说明2.5 存储方案的不足 03.存储方案原理 3.1 Sp存储原理分析3.2 MMKV存储…...
sheng的学习笔记Eureka Ribbon
Eureka-注册中心Eureka简介官方网址:https://spring.io/projects/spring-cloud-netflixEureka介绍Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现(请对比Zookeeper)。Zooleeper nacos.Eureka 采用了 C-S 的设计架构。Eureka Server 作为服…...
零代码工具我推荐Oracle APEX
云原生时代零代码工具我推荐Oracle APEX 国内的低码开发平台我也看了很多,感觉还是不太适合我这个被WEB抛弃的老炮。自从看了Oracle APEX就不打算看其它的了。太强大了,WEB服务器都省了,直接数据库到WEB页面。功能很强大,震撼到我…...
InstructGPT方法简读
InstructGPT方法简读 引言 仅仅通过增大模型规模和数据规模来训练更大的模型并不能使得大模型更好地理解用户意图。由于数据的噪声极大,并且现在的大多数大型语言模型均为基于深度学习的“黑箱模型”,几乎不具有可解释性和可控性,因此&…...
SpringCloud-5_模块集群化
避免一台Server挂掉,影响整个服务,搭建server集群创建e-commerce-eureka-server-9002微服务模块【作为注册中心】创建步骤参考e-commerce-eureka-server-9001修改pom.xml,加入依赖同9001创建resources/application.yml9002的ymlserver: # 修改端口号por…...
AQS底层源码深度剖析-BlockingQueue
目录 AQS底层源码深度剖析-BlockingQueue BlockingQueue定义 队列类型 队列数据结构 ArrayBlockingQueue LinkedBlockingQueue DelayQueue BlockingQueue API 添加元素 检索(取出)元素 BlockingQueue应用队列总览图 AQS底层源码深度剖析-BlockingQueue【重点中的重…...
Kotlin协程:Flow的异常处理
示例代码如下:launch(Dispatchers.Main) {// 第一部分flow {emit(1)throw NullPointerException("e")}.catch {Log.d("liduo", "onCreate1: $it")}.collect {Log.d("liudo", "onCreate2: $it")}// 第二部分flow …...
qt下ffmpeg录制mp4经验分享,支持音视频(h264、h265,AAC,G711 aLaw, G711muLaw)
前言 MP4,是最常见的国际通用格式,在常见的播放软件中都可以使用和播放,磁盘空间占地小,画质一般清晰,它本身是支持h264、AAC的编码格式,对于其他编码的话,需要进行额外处理。本文提供了ffmpeg录…...
C#读取Excel解析入门-1仅围绕三个主要的为阵地,进行重点解析,就是最理性的应对上法所在
业务中也是同样的功能点实现。只是多扩展了很多代码,构成了项目的其他部分,枝干所在。但是有用的枝干,仅仅不超过三个主要的!所以您仅仅围绕三个主要的为阵地,进行重点解析,就是最理性的应对上法所在了 str…...
一起Talk Android吧(第五百一十八回:在Android中使用MQTT通信五)
文章目录 知识回顾问题描述解决过程经验分享各位看官们大家好,这一回中咱们说的例子是" 在Android中使用MQTT通信五",本章回内容与前后章节内容无关联。闲话休提,言归正转,让我们一起Talk Android吧! 知识回顾 我们在前面章回中介绍了如何使用MQTT通信,包含它…...
100种思维模型之混沌与秩序思维模型-027
人类崇尚秩序与连续性,我们习惯于我们的日常世界,它以线性方式运作,没有不连续或突跳。 为此,我们学会了期望各种过程以连续方式运行,我们的内心为了让我们更有安全感,把很多事物的结果归于秩序,…...
Java开发 - Redis初体验
前言 es我们已经在前文中有所了解,和es有相似功能的是Redis,他们都不是纯粹的数据库。两者使用场景也是存在一定的差异的,本文目的并不重点说明他们之间的差异,但会简要说明,重点还是在对Redis的了解和学习上。学完本…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
