当前位置: 首页 > news >正文

工作实战之拦截器模式

目录

前言

一、结构中包含的角色

二、拦截器使用

1.拦截器角色

 a.自定义拦截器UserValidateInterceptor,UserUpdateInterceptor,UserEditNameInterceptor

 b.拦截器配置者UserInterceptorChainConfigure,任意组装拦截器顺序

c.拦截器管理者UserInterceptorChainManager

2.运行结果展示

a.使用代码

三、拦截器调用解说

1.项目启动,初始化bean

2.方法执行 

四、代码下载

总结


前言

拦截过滤器模式,简称拦截器模式,是责任链模式的一种衍生模式。用于对业务程序做一些预处理/后处理


一、结构中包含的角色

  1. Interceptor(抽象处理者)
  2. InterceptorChain(责任链)
  3. InterceptorChainBuilder(责任链建造者)
  4. AbstractInterceptorChainManager(链条管理者)
  5. 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&#xff0c;UserUpdateInterceptor&#xff0c;UserEditNameInterceptor b.拦截器配置者UserInterceptorChainConfigure&#xff0c;任意组装拦截器顺序 c.拦截器管理者…...

某美颜app sig参数分析

之前转载过该app的文章&#xff0c;今天翻版重新整理下&#xff0c;版本号:576O5Zu56eA56eAYXBwIHY5MDgw (base64 解码)。 上来先抓个包&#xff1a; jadx搜索关键词 "sigTime"&#xff0c;然后定位到这里 看这行代码 cVar.addForm(INoCaptchaComponent.sig, genera…...

Linux - Linux系统优化思路

文章目录影响Linux性能的因素CPU内存磁盘I/O性能网络宽带操作系统相关资源系统安装优化内核参数优化文件系统优化应用程序软件资源系统性能分析工具vmstat命令iostat命令sar命令系统性能分析标准小结影响Linux性能的因素 CPU CPU是操作系统稳定运行的根本&#xff0c;CPU的速…...

2.Elasticsearch入门

2.Elasticsearch入门[toc]1.Elasticsearch简介Elasticsearch是用Java开发并且是当前最流行的开源的企业级搜索引擎。 能够达到实时搜索&#xff0c;稳定&#xff0c;可靠&#xff0c;快速&#xff0c;安装使用方便。客户端支持Java、.NET&#xff08;C#&#xff09;、PHP、Pyth…...

RK3399平台开发系列讲解(应用开发篇)断言的使用

🚀返回专栏总目录 文章目录 一、什么是断言二、静态断言三、运行时断言沉淀、分享、成长,让自己和他人都能有所收获!😄 📢断言为我们提供了一种可以静态或动态地检查程序在目标平台上整体状态的能力,与它相关的接口由头文件 assert.h 提供。 一、什么是断言 在编程中…...

云原生系列之使用prometheus监控nginx

前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓月&#xff0c;本文主要讲解云原生系列之使用prometheus监控nginx 文章收录到 csdn 我是沐风晓月的博客【prometheus监控系列】专栏&#xff0c;此专栏是沐风晓月对云原生prometheus的的总结&#xff0c;希望能够加深自…...

第六届省赛——8移动距离(总结规律)

题目&#xff1a;X星球居民小区的楼房全是一样的&#xff0c;并且按矩阵样式排列。其楼房的编号为1,2,3...当排满一行时&#xff0c;从下一行相邻的楼往反方向排号。比如&#xff1a;当小区排号宽度为6时&#xff0c;开始情形如下&#xff1a;1 2 3 4 5 612 11 10 9 8 713 14 1…...

C++vector 简单实现

一。概述 vector是我们经常用的一个容器&#xff0c;其本质是一个线性数组。通过对动态内存的管理&#xff0c;增删改查数据&#xff0c;达到方便使用的目的。 作为一个线性表&#xff0c;控制元素个数&#xff0c;容量&#xff0c;开始位置的指针分别是&#xff1a; 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简介官方网址&#xff1a;https://spring.io/projects/spring-cloud-netflixEureka介绍Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现(请对比Zookeeper)。Zooleeper nacos.Eureka 采用了 C-S 的设计架构。Eureka Server 作为服…...

零代码工具我推荐Oracle APEX

云原生时代零代码工具我推荐Oracle APEX 国内的低码开发平台我也看了很多&#xff0c;感觉还是不太适合我这个被WEB抛弃的老炮。自从看了Oracle APEX就不打算看其它的了。太强大了&#xff0c;WEB服务器都省了&#xff0c;直接数据库到WEB页面。功能很强大&#xff0c;震撼到我…...

InstructGPT方法简读

InstructGPT方法简读 引言 仅仅通过增大模型规模和数据规模来训练更大的模型并不能使得大模型更好地理解用户意图。由于数据的噪声极大&#xff0c;并且现在的大多数大型语言模型均为基于深度学习的“黑箱模型”&#xff0c;几乎不具有可解释性和可控性&#xff0c;因此&…...

SpringCloud-5_模块集群化

避免一台Server挂掉&#xff0c;影响整个服务&#xff0c;搭建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的异常处理

示例代码如下&#xff1a;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&#xff0c;是最常见的国际通用格式&#xff0c;在常见的播放软件中都可以使用和播放&#xff0c;磁盘空间占地小&#xff0c;画质一般清晰&#xff0c;它本身是支持h264、AAC的编码格式&#xff0c;对于其他编码的话&#xff0c;需要进行额外处理。本文提供了ffmpeg录…...

C#读取Excel解析入门-1仅围绕三个主要的为阵地,进行重点解析,就是最理性的应对上法所在

业务中也是同样的功能点实现。只是多扩展了很多代码&#xff0c;构成了项目的其他部分&#xff0c;枝干所在。但是有用的枝干&#xff0c;仅仅不超过三个主要的&#xff01;所以您仅仅围绕三个主要的为阵地&#xff0c;进行重点解析&#xff0c;就是最理性的应对上法所在了 str…...

一起Talk Android吧(第五百一十八回:在Android中使用MQTT通信五)

文章目录 知识回顾问题描述解决过程经验分享各位看官们大家好,这一回中咱们说的例子是" 在Android中使用MQTT通信五",本章回内容与前后章节内容无关联。闲话休提,言归正转,让我们一起Talk Android吧! 知识回顾 我们在前面章回中介绍了如何使用MQTT通信,包含它…...

100种思维模型之混沌与秩序思维模型-027

人类崇尚秩序与连续性&#xff0c;我们习惯于我们的日常世界&#xff0c;它以线性方式运作&#xff0c;没有不连续或突跳。 为此&#xff0c;我们学会了期望各种过程以连续方式运行&#xff0c;我们的内心为了让我们更有安全感&#xff0c;把很多事物的结果归于秩序&#xff0c…...

Java开发 - Redis初体验

前言 es我们已经在前文中有所了解&#xff0c;和es有相似功能的是Redis&#xff0c;他们都不是纯粹的数据库。两者使用场景也是存在一定的差异的&#xff0c;本文目的并不重点说明他们之间的差异&#xff0c;但会简要说明&#xff0c;重点还是在对Redis的了解和学习上。学完本…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...