工作实战之拦截器模式
目录
前言
一、结构中包含的角色
二、拦截器使用
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的了解和学习上。学完本…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...
