工作实战之拦截器模式

news2025/7/30 18:35:04

目录

前言

一、结构中包含的角色

二、拦截器使用

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
     */
    @Override
    public void interceptor(User user) {
        if(user.getAge() != 10) {
            throw new CommonException("年龄不对");
        }
        System.out.println("校验用户"+user);
    }
}

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

@Component
public class UserInterceptorChainConfigure
        implements InterceptorChainConfigure<User,InterceptorChainBuilder<User>> {
    /**
     * 拦截器链配置
     *
     * @param interceptorChainBuilder 拦截器链构造器
     */
    @Override
    public 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 {

    @Autowired
    private UserInterceptorChainManager userInterceptorChainManager;

    @Autowired
    private 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解决,业务自己的拦截器链模式,可以解决繁琐业务重复代码的问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/394528.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VM安装FydeOS16.0

准备工作 1、已安装VMware Workstation虚拟机&#xff1b; 2、下载好系统文件&#xff1b; 3、打开VM、新建虚拟机&#xff1b; 一、下载 https://fydeos.com/download/vm 我选择的镜像1。等下载完成&#xff0c;我这感觉下载速度不快&#xff0c;通过onedrive下载要快。 …

Jfrog 搭建本地maven仓库以及上传Android库

Jfrog 下载 安装包下载地址&#xff1a;Download Artifactory OSS | JFrog 如果是想下载之前的版本&#xff0c;可以点击上面的Get code source &#xff0c;如果是最新版本&#xff0c;直接点下面的下载就好。下面以Linux安装为例。 Jfrog安装 对于Linux而言&#xff0c;其实…

Java泛型深入

一. 泛型的概述和优势 泛型概述 泛型&#xff1a;是JDK5中引入的特性&#xff0c;可以在编译阶段约束操作的数据类型&#xff0c;并进行检查。泛型的格式&#xff1a;<数据类型>&#xff0c;注意&#xff1a;泛型只能支持引用数据类型。集合体系的全部接口和实现类都是…

Java刷题-----蓝桥杯省赛JavaC组第十二届(第二场)4-------------6

4、格点题目本题总分&#xff1a;10 分问题描述如果一个点 ( x , y ) 的两维坐标都是整数&#xff0c;即 x ∈ Z 且 y ∈ Z &#xff0c;则称这个点为一个格点。如果一个点 ( x , y ) 的两维坐标都是正数&#xff0c;即 x > 0 且 y > 0 &#xff0c;则称这个点在第一象限…

浅谈 Nodejs原型链污染

一直在做php的题目&#xff0c;对其它语言做的很少。刚好在西湖论剑2022复现时&#xff0c;遇到了一道原型链污染的题目&#xff0c;借此机会开始简单学习一下 Nodejs的洞 p&#x1f402;讲解的十分清楚&#xff0c;因此下面举例子就直接用p&#x1f402;的例子进行解释了 目…

SNMP学习和测试

学习 &#xff08;1&#xff09;SNMP是简单网络管理协议&#xff0c;但是多么晦涩我就不说了。 &#xff08;2&#xff09;SNMP工作在应用层&#xff0c;也就是通过socket实现的&#xff0c;基于UDP&#xff0c;端口161和162&#xff0c;161是用于和网管通信的端口&#xff0…

NYUv2生成边界GT(1)

看了cityscape和NYUv2生成边界GT的代码后&#xff0c;因为自己使用的是NYUv2数据集&#xff0c;所以需要对自己的数据集进行处理。CASENet生成边界GT所使用的代码是MATLAB&#xff0c;所以又重新看了一下MATLAB的代码&#xff0c;并进行修改&#xff0c;生成了自己的边界代码。…

Chrome开发使用技巧总结

Chrome一个程序员开发神器&#xff0c;但是好多猿子们不会或者没有正确使用。今天教大家如何利用它快速高效的开发调试工作。代码格式化有很多css/js的代码都会被 minify 掉&#xff0c;你可以点击代码窗口左下角的那个 { } 标签&#xff0c;chrome会帮你给格式化掉。强制DOM状…

基于同步整流技术的Buck变换器研究

基于同步整流技术的Buck变换器研究 摘要 B u c k 变换器作为一种基本的开关电源变换器&#xff0c;在电力变换场合具有广泛的应用。 为解决 B u c k 变换器工作在电感电流连续状态下&#xff0c;续流二极管关断时存在较大的反向电流过冲问题&#xff0c;采用了同步整流技术。…

Spark高手之路2—Spark安装配置

文章目录Spark 运行环境一、Local 模式1. 下载压缩包2.上传到服务器3. 解压4. 启动 Local 环境5. 命令行工具6. 退出本地模式7. 提交应用二、Standalone 模式1. 解压2. 修改配置文件1&#xff09;进入解压缩后路径的 conf 目录&#xff0c;复制 workers.template 文件为 worker…

人人都学会APP开发 提高就业竞争力 简单实用APP应用 安卓浏览器APP 企业内部通用APP制作 制造业通用APP

安卓从2009年开始流程于手机、平板&#xff0c;已经是不争的非常强大生产力工具&#xff0c;更为社会创造非常高的价值&#xff0c;现在已经是202X年&#xff0c;已经十几年的发展&#xff0c;安卓平台已经无所不在。因此建议人人都学学APP制作&#xff0c;简易入门&#xff0c…

JavaSe第6次笔记

1.不建议使用c语言的数组的表示方法。 2.二维数组表示方法 3.数组整体初始化时&#xff0c;只能在定义时初始化。 int[] array; array new int[]{1, 2}; 4. boolean类型数组&#xff0c;默认值是false&#xff0c;String类型数组&#xff0c;默认是null&#xff0c;其它是…

CHAPTER 2 目录及文件

目录及文件1 目录1.1 目录结构1.2 核心目录2 文件2.1 /etc/中的文件2.1.1 修改主机名(/etc/hostname)2.1.2 网卡配置文件2.1.3 开机自启动配置文件(/etc/rc.local)2.1.4 /etc/motd和/etc/issue2.2 /var/中的文件2.3 /proc/中的文件2.3.1 CPU信息(lscpu)3 文件类型3.1 类型说明3…

Golang中GC和三色屏障机制【Golang面试必考】

文章目录Go v1.3 标记—清楚(mark and sweep)方法Go V1.5 三色标记法三色标记过程无STW的问题强弱三色不变式插入写屏障Go V1.8的三色标记法混合写屏障机制混合写屏障场景场景1:对象被一个堆对象删除引用&#xff0c;成为栈对象的下游场景2:对象被一个栈对象删除引用&#xff0…

PyQt 做美*女GIF设置桌面,每天都很爱~

人生苦短&#xff0c;我用python 要说程序员工作的最大压力不是来自于工作本身&#xff0c; 而是来自于需要不断学习才能更好地完成工作&#xff0c; 因为程序员工作中面对的编程语言是在不断更新的&#xff0c; 同时还要学习熟悉其他语言来提升竞争力… 好了&#xff0c;学习…

python模块引入问题和解决方案_真方案不骗人

1.pycharm运行python脚本的过程 使用pycharm等编辑器run/debug运行python脚本时&#xff0c;编辑器会通过本地python命令全路径执行脚本&#xff0c;例如 D:\DevelopTools\Python\python.exe D:/Codes/一长串路径/bbss_nature_python/demo/test_no_param_in.py 并且会在pyth…

自动化框架如何搭建?让10年阿里自动化测试老司机帮你搞定!自动化测试脚本怎么写?

一、何为框架&#xff1f;何为自动化测试框架&#xff1f; 无论是日常技术交流&#xff0c;还是在自动化测试实践中&#xff0c;经常会听到一个词叫&#xff1a;框架。之前对“框架”这个词知其然不知其所以然。现在看过一些资料以及加上我自己的一些实践有了我自己的一些看法…

PowerJob中的Vert.x的应用,是点睛之笔还是大材小用?我感觉有点故意炫技啊

这是一篇为了参加活动写得文章&#xff0c;不知道为什么&#xff0c;写得时候网络巨差&#xff0c;我是顶着闹心发上来的&#xff0c;最后大家女神节快乐。 最近难得忙了一下&#xff0c;领导让我从Vert.x和lagom中技术选型&#xff0c;因为lagom是scala写得&#xff0c;我虽然…

2023高质量设计竞赛汇总,想证明自己实力的快来

对于设计师来说&#xff0c;参加设计比赛不仅能够提升自己的设计能力&#xff0c;也是一条证明实力最好的捷径。小编也收集整理了不少近期设计大赛&#xff0c;分别标注了截止日期和官网等&#xff0c;宝子们记得码住收藏&#xff0c;赶紧SHOW起来&#xff01;优酷X站酷 一千零…

湖南媒体资源有哪些?湖南媒体邀约怎么做?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 湖南位于中国中南部&#xff0c;以其美丽的自然风光、丰富的历史文化和独特的湖湘文化而著名&#xff0c;拥有丰富的媒体资源。以下是一些湖南省的媒体资源&#xff1a; 1.湖南日报社: …