如何设计一个@TenantIgnore功能,使得被该注解注解的方法可以使用户绕过自己的租户id查询全局信息(所有租户的信息)

什么是@TelnantIgnore

有些系统设计时,将不同公司(租户)的数据放在同一个数据库(表)中,因此会员A在查询数据时,应只查询本人所在公司的数据,因此会在某些表每个执行的sql语句中默认加上"where tenantid = ?"来限制用户的行为。但是也有一些全局的查询,要查询所有公司的所有数据,因此需要在该Controller的方法上加上@TelnantIgnore,使该方法绕过加"where tenantid = ?"这个步骤。


如何做

这是一个非常经典的AOP + ThreadLocal + ORM 插件协同工作的架构设计案例。

如果你要从零设计一个@TenantIgnore功能,让被注解的方法能够绕过租户限制查询全局数据,你需要构建一条完整的指令传输链

我们可以把这个过程分为4 个核心步骤,就像设计一套“免检通行”系统:


第一步:制作通行证(定义注解)

首先,你需要定义一个注解,作为一个“标记”。

// 1. 定义注解 @TenantIgnore@Target({ElementType.METHOD,ElementType.TYPE})// 既能加在方法上,也能加在类上@Retention(RetentionPolicy.RUNTIME)// 运行时必须存在public@interfaceTenantIgnore{// 可以扩展属性,比如 boolean value() default true;}

第二步:准备口袋(定义上下文 Holder)

你需要一个地方来存放“是否免检”这个状态。因为 Web 请求是基于线程的,所以必须用ThreadLocal

// 2. 定义上下文容器 TenantContextHolderpublicclassTenantContextHolder{// 使用 ThreadLocal 保证线程隔离privatestaticfinalThreadLocal<Boolean>IGNORE=newThreadLocal<>();// 设置状态publicstaticvoidsetIgnore(Booleanignore){IGNORE.set(ignore);}// 获取状态(供 MyBatis 插件读取)publicstaticbooleanisIgnore(){returnBoolean.TRUE.equals(IGNORE.get());}// 清理(防止内存泄漏和线程污染)publicstaticvoidclear(){IGNORE.remove();}}

第三步:门口安检员(编写 AOP 切面)

这是核心逻辑。你需要拦截所有贴了@TenantIgnore的方法,在方法执行把“免检卡”塞进口袋,执行把卡拿出来。

// 3. 定义切面 TenantIgnoreAspect@Aspect@ComponentpublicclassTenantIgnoreAspect{@Around("@annotation(tenantIgnore)")// 拦截所有带 @TenantIgnore 的方法publicObjectaround(ProceedingJoinPointjoinPoint,TenantIgnoretenantIgnore)throwsThrowable{// A. 存档:先记住进门前的状态(防止嵌套调用时,把外层的状态搞丢)booleanoldIgnore=TenantContextHolder.isIgnore();try{// B. 塞卡:标记当前线程为“忽略租户”TenantContextHolder.setIgnore(true);// C. 放行:执行真正的业务逻辑(查询数据库)returnjoinPoint.proceed();}finally{// D. 复原:无论成功失败,必须把状态恢复成进门前的样子// 这一步至关重要!否则线程池复用会导致下一个请求数据泄露!TenantContextHolder.setIgnore(oldIgnore);}}}

第四步:修改数据库规则(配置 MyBatis Plus Handler)

最后,你需要告诉 MyBatis Plus:“生成 SQL 之前,先去口袋里摸一下,看看有没有免检卡。”

// 4. 配置 MyBatis Plus 的多租户拦截器@ComponentpublicclassMyTenantLineHandlerimplementsTenantLineHandler{@OverridepublicExpressiongetTenantId(){// 返回当前用户的租户ID,例如 1returnnewLongValue(UserContext.getTenantId());}@OverridepublicStringgetTenantIdColumn(){return"tenant_id";// 数据库里的列名}// 【核心】决定是否要忽略表(不加 WHERE tenant_id = ?)@OverridepublicbooleanignoreTable(StringtableName){// 1. 系统表(如字典、菜单)默认忽略if("sys_dict".equals(tableName)){returntrue;}// 2. 【关键】去口袋(ThreadLocal)里查状态// 如果 Aspect 设置了 true,这里就返回 true -> MyBatis Plus 就不会拼接租户条件了if(TenantContextHolder.isIgnore()){returntrue;}// 3. 默认不忽略returnfalse;}}

🌟 总结:完整的执行流

当你写下这段代码时:

@TenantIgnore// 1. 贴上标记publicList<User>getAllUsers(){returnuserMapper.selectList(null);// 2. 查库}

系统底层发生了什么:

  1. AOP 介入:Aspect 看到注解,调用TenantContextHolder.setIgnore(true)。此时当前线程的ThreadLocal变为true
  2. 业务执行:代码跑到userMapper.selectList
  3. MP 拦截:MyBatis Plus 准备生成 SQL,问MyTenantLineHandler:“我要不要加租户条件?”
  4. Handler 检查:Handler 调用TenantContextHolder.isIgnore(),发现是true
  5. SQL 生成:Handler 说“不用加”。MP 生成SELECT * FROM user(全表查询)。
  6. AOP 收尾:方法返回,Aspect 在finally块中清理ThreadLocal

这就是通过注解驱动实现动态数据权限控制的标准架构设计。

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

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

相关文章

EmotiVoice模型微调指南:针对特定领域优化语音表现

EmotiVoice模型微调指南&#xff1a;针对特定领域优化语音表现 在虚拟助手逐渐走进千家万户、数字人开始主持直播带货的今天&#xff0c;用户早已不再满足于“能说话”的机器语音。他们期待的是有温度、有情绪、甚至能模仿亲人声音的个性化表达。这种需求背后&#xff0c;是对文…

windows的任务管理器中如何查看与硬盘相关的指标?

硬盘&#xff08;特别是传统的机械硬盘HDD&#xff09;是Windows系统中最容易成为性能瓶颈的部件。在任务管理器中&#xff0c;理解硬盘指标是诊断“电脑莫名卡顿、操作不跟手”的关键。一、找到硬盘指标 打开任务管理器 (Ctrl Shift Esc)。切换到“性能”选项卡。点击左侧的…

【心电图信号处理】心电图信号处理(含基础波形检测、信号去噪、信号重建指标)【含Matlab源码 14715期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;Matlab武动乾坤博客之家&#x1f49e;…

EmotiVoice语音合成服务高并发架构设计

EmotiVoice语音合成服务高并发架构设计 在内容平台、虚拟偶像和智能交互设备日益普及的今天&#xff0c;用户对语音输出的要求早已不再满足于“能说”&#xff0c;而是追求“说得像人”——有情感、有个性、有温度。传统的文本转语音&#xff08;TTS&#xff09;系统虽然稳定高…

【情绪识别】基于matlab心率变异性信号的持续情绪识别方法【含Matlab源码 14718期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到海神之光博客之家&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49…

如何训练自定义情感模型以扩展EmotiVoice能力?

如何训练自定义情感模型以扩展EmotiVoice能力&#xff1f; 在虚拟助手越来越频繁地走进家庭、客服系统逐步取代人工坐席的今天&#xff0c;一个共通的问题浮出水面&#xff1a;为什么这些“会说话”的AI听起来总少了点人味&#xff1f;答案或许就藏在情感表达的缺失中。机械的语…

【情绪识别】心率变异性信号的持续情绪识别方法【含Matlab源码 14718期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;Matlab武动乾坤博客之家&#x1f49e;…

【预编码】基于matlab深度学习的带有有限字母表信令MIMO通道线性预编码【含Matlab源码 14717期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到海神之光博客之家&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49…

从零到一:构建智能红蓝对抗训练可视化系统——一场技术与战术的完美融合

下载链接:https://download.csdn.net/download/weixin_44603934/92467360 引言:当AI遇见军事仿真 在人工智能与军事训练深度融合的今天,如何构建一个既能真实模拟战场对抗,又能提供直观可视化分析的系统,成为技术领域的热点。今天分享一个完整的红蓝对抗训练可视化系统,…

EmotiVoice语音合成质量评估标准与优化建议

EmotiVoice语音合成质量评估与优化实践 在虚拟主播深夜直播、智能客服温柔应答、游戏NPC情绪爆发的今天&#xff0c;我们早已不再满足于“能说话”的AI语音——用户要的是“有情绪”“像真人”“能共情”的声音。传统TTS系统还在用固定语调朗读文本时&#xff0c;EmotiVoice这样…

任务管理器和资源管理器的关系和区别

任务管理器和资源管理器是Windows中两个核心但功能完全不同的工具。简单来说&#xff0c;一个是“程序与性能监控中心”&#xff0c;一个是“文件与系统导航中心”。一、 一句话定义 任务管理器 (Taskmgr.exe)&#xff1a;系统的“进程监控与性能仪表盘”。用于查看、管理和结束…

6、自旋、量子比特与纠缠:量子世界的奇妙之旅

自旋、量子比特与纠缠:量子世界的奇妙之旅 1. 光子测量与数学模型 在量子物理中,光子的测量是一个有趣的研究方向。当进行三次测量时,通过第一个滤波器的光子会处于特定状态。设通过第一个滤波器的光子状态为 $\begin{bmatrix}1\0\end{bmatrix}$ 。 第二个测量对应于通过…

43、Red Hat系统安全维护与监控指南

Red Hat系统安全维护与监控指南 1. 密码破解警告 在使用密码破解工具(如Crack)时,如果不使用 -quiet 开关,会收到关于锁定账户和无有效密码账户的警告信息。像用于运行打印和Web服务(如lpd和apache)的账户,通常会配置成这样,以防止他人以这些用户身份登录。 重要提…

EmotiVoice能否替代专业配音演员?我们做了测试

EmotiVoice能否替代专业配音演员&#xff1f;我们做了测试 在一部独立游戏的开发团队中&#xff0c;原本需要为上百个NPC录制上千条语音——每句台词都得请配音演员反复试音、调整情绪、后期剪辑。整个流程耗时三周&#xff0c;成本超过五万元。而现在&#xff0c;他们只用了三…

1.3 衡量AI的标准:图灵测试、中文房间与认知科学的视角

1.3 衡量AI的标准&#xff1a;图灵测试、中文房间与认知科学的视角 如何判定一个系统是否具有“智能”&#xff0c;是人工智能领域自诞生以来便伴随的根本性问题。确立一个有效的衡量标准&#xff0c;不仅关乎对技术进展的评估&#xff0c;更触及智能的本质与认知的哲学基础。本…

EmotiVoice语音合成缓存机制设计提升性能

EmotiVoice语音合成缓存机制设计提升性能 在智能客服、虚拟偶像和游戏NPC对话日益普及的今天&#xff0c;用户早已不再满足于“能出声”的机械朗读。他们期待的是有温度、有情绪、像真人一样的语音交互体验。EmotiVoice作为一款开源的多情感TTS引擎&#xff0c;正是为这一目标而…

1、量子计算基础:从比特到量子比特

量子计算基础:从比特到量子比特 在计算领域,数据的处理和传输是核心任务。经典计算以比特为基本数据单元,而量子计算则以量子比特(qubit)为基础。这两者有着显著的区别,下面我们将深入探讨。 经典比特与量子比特的区别 经典比特只能处于两种状态之一,就像一个简单的开…

37、深入探究:Linux内核的重建与优化

深入探究:Linux内核的重建与优化 1. Linux内核概述 Linux内核作为Linux操作系统的核心,承担着诸多关键职责。它不仅为底层硬件提供接口,处理应用程序与硬件间的所有通信,还负责一系列重要任务,具体如下: - 进程管理 :涵盖进程的创建、调度和终止。 - 进程间通信 …

EmotiVoice语音合成与ASR系统的闭环测试实践

EmotiVoice语音合成与ASR系统的闭环测试实践 在智能客服、虚拟助手和有声内容创作日益普及的今天&#xff0c;用户对语音交互的期待早已超越“能听清”这一基本要求。他们希望听到的声音不仅是准确的&#xff0c;更是富有情绪、贴近真人、甚至具备个性化风格的。然而&#xff0…

38、Linux 系统管理与 Perl 编程全解析

Linux 系统管理与 Perl 编程全解析 1. Linux 系统管理基础操作 在 Linux 系统管理中,使用 chroot 命令可以切换根分区,操作如下: # chroot /mnt/sysimage执行此命令后,可尝试恢复原 /boot 分区,看是否能成功启动系统。 2. Linux 系统管理的多个方面 Linux 系统管…