交叉业务:AOP 要解决的核心问题
交叉业务AOP 要解决的核心问题一、什么是交叉业务交叉业务更标准的叫法是横切关注点Cross-Cutting Concerns。它指的是那些不属于某个具体业务逻辑却散布在多个业务模块中、被反复调用的通用逻辑。比如日志记录、事务控制、权限校验、性能监控、缓存处理、异常统一处理。这些逻辑几乎每个业务方法都需要但它们本身又不是“用户注册”“下单支付”这类核心业务。核心业务回答的是“这个功能要做什么”交叉业务回答的是“这个功能在运行时还需要什么额外保障”。二、交叉业务带来的问题假设一个 Service 里有多个业务方法每个方法都要写日志、开事务、检查权限publicvoidregister(Useruser){log.info(开始注册用户user.getName());// 日志TransactiontxtransactionManager.begin();// 事务try{if(!currentUser.hasPermission(user:add)){// 权限thrownewPermissionDeniedException();}userDao.save(user);// 核心业务tx.commit();log.info(注册成功);}catch(Exceptione){tx.rollback();log.error(注册失败,e);throwe;}}publicvoidupdateUser(Useruser){log.info(开始更新用户user.getName());// 同样的日志TransactiontxtransactionManager.begin();// 同样的事务try{if(!currentUser.hasPermission(user:update)){// 同样的权限thrownewPermissionDeniedException();}userDao.update(user);// 核心业务tx.commit();log.info(更新成功);}catch(Exceptione){tx.rollback();log.error(更新失败,e);throwe;}}这里真正的业务逻辑只有userDao.save(user)或userDao.update(user)一行其他全是交叉业务。问题很明显代码重复每个方法都要写一遍日志、事务、权限。耦合严重业务代码和通用逻辑混在一起改日志格式要改所有方法。维护困难新增一个方法就要复制一遍模板代码容易漏掉某个步骤。可读性差核心业务被淹没在大量非业务代码中。这种代码结构叫做代码纠缠Code Tangling和代码散落Code Scattering。交叉业务散落在各个模块里和核心业务纠缠在一起。三、AOP 如何解决交叉业务AOP 的思路是把交叉业务从核心业务中抽离出来放到独立的切面Aspect里通过动态代理在运行时织入。抽离后业务方法只剩下核心逻辑ServicepublicclassUserService{TransactionalLog(注册用户)RequiresPermission(user:add)publicvoidregister(Useruser){userDao.save(user);// 只有核心业务}TransactionalLog(更新用户)RequiresPermission(user:update)publicvoidupdateUser(Useruser){userDao.update(user);// 只有核心业务}}日志、事务、权限的实现都在各自的切面里AspectComponentpublicclassLogAspect{Around(annotation(log))publicObjectlog(ProceedingJoinPointpjp,Loglog)throwsThrowable{System.out.println(开始log.value());Objectresultpjp.proceed();System.out.println(完成log.value());returnresult;}}AspectComponentpublicclassTransactionAspect{Around(annotation(org.springframework.transaction.annotation.Transactional))publicObjecttransaction(ProceedingJoinPointpjp)throwsThrowable{// 开启事务、提交、回滚}}AspectComponentpublicclassPermissionAspect{Before(annotation(requiresPermission))publicvoidcheck(RequiresPermissionrequiresPermission){// 权限校验}}业务代码干净了交叉业务集中管理了修改日志格式只需要改LogAspect一个地方。四、常见的交叉业务类型交叉业务说明Spring 中的实现日志记录记录方法调用、参数、返回值自定义切面事务管理开启、提交、回滚事务Transactional权限校验方法执行前检查权限PreAuthorize、自定义切面缓存查询缓存、更新缓存Cacheable、CacheEvict性能监控统计方法执行耗时自定义切面异常处理统一捕获、转换、记录异常ControllerAdvice、自定义切面限流控制方法调用频率自定义切面幂等保证方法重复调用结果一致自定义切面五、交叉业务和核心业务的关系对比维度核心业务交叉业务关注点业务规则、数据处理通用保障、非功能性需求变化频率随需求变化相对稳定适用范围特定模块或方法多个模块、多个方法代码位置Service 方法内部切面中是否可复用低业务相关高通用典型例子注册、下单、支付日志、事务、权限核心业务是“做什么”交叉业务是“怎么做才安全、可追踪、可控制”。两者关注点不同但目标一致让系统正确、稳定、可维护。六、AOP 处理交叉业务的关键点切点要精确用execution、annotation等表达式明确指定哪些方法需要增强。切点写得太宽会拦截不必要的方法写得太窄会漏掉需要增强的方法。通知类型要选对前置校验用Before事务和缓存用Around异常处理用AfterThrowing。注意内部调用失效同一个类中方法 A 调用方法 BB 的切面不会生效。需要注入自身代理或使用AopContext.currentProxy()。避免切面嵌套过深多个切面叠加时执行顺序由Order控制。顺序不对可能导致事务和缓存的行为不符合预期。七、总结交叉业务是 AOP 要解决的核心问题。它指的是那些散布在多个业务模块中、与核心业务无关却又必不可少的通用逻辑如日志、事务、权限、缓存、监控。维度说明标准叫法横切关注点Cross-Cutting Concerns核心问题代码散落、代码纠缠、重复、难维护解决方式AOP 抽离到切面动态代理织入常见类型日志、事务、权限、缓存、监控、异常业务代码只保留核心业务逻辑切面代码集中管理交叉业务注意事项切点精确、通知选对、内部调用失效理解交叉业务就理解了 AOP 存在的意义。AOP 不是为了炫技而是为了把那些“每个方法都要做一遍”的事情从业务代码中拿出去统一放到一个地方管理。业务代码只负责业务交叉逻辑只负责保障各司其职。

相关新闻

定义与赋值 | C指针基础(一)

定义与赋值 | C指针基础(一)

C指针基础(一)什么是指针指针的意义:为什么要多此一举?总结定义指针变量基本格式为什么定义指针时需要指定类型名?指针变量的赋值&与*辨析:pa、*pa 与 &pa什么是指针 指针,说白了就是内…

2026/10/4 18:55:04 阅读更多 →
c++学习(18):多线程基础

c++学习(18):多线程基础

//7. 多线程基础//并行模拟两个独立的门电路&#xff08;简单示例&#xff09;。#include <iostream> #include <thread> #include <vector> #include <chrono>// 模拟一个耗时计算 int simulateGate(int id, int delayMs) {std::this_thread::sleep_f…

2026/10/4 18:55:04 阅读更多 →
新手小白 Agent 开发第9课:从小白到独立开发,完整路线图与认知升级

新手小白 Agent 开发第9课:从小白到独立开发,完整路线图与认知升级

前 8 课&#xff0c;我们从装 Python 一直做到了网页版 Agent。这一课不再写新代码&#xff0c;而是帮你把零散的知识点串成一张地图&#xff0c;并纠正三个最容易让初学者走弯路的认知。一、完整路线图&#xff1a;6 个阶段如果你是零基础&#xff0c;照着这条线走&#xff0c…

2026/10/4 18:55:04 阅读更多 →

最新新闻

Trade.dll与TradeX.dll调用避坑指南:通达信程序化交易接口实战

Trade.dll与TradeX.dll调用避坑指南:通达信程序化交易接口实战

简介&#xff1a;面向量化交易与程序化交易开发者的通达信交易接口资料包&#xff0c;整合老版Trade.dll与新一代TradeX.dll行情交易二合一接口&#xff0c;通过TdxTradeServer将交易请求封装为HTTP REST API&#xff0c;解决DLL直连的跨语言调用与远程接入难题&#xff0c;适用…

2026/10/4 21:56:06 阅读更多 →
AI论文网站排行:10款避坑,毕业生真心推荐TaoToken

AI论文网站排行:10款避坑,毕业生真心推荐TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 21:56:06 阅读更多 →
内存压力测试实战指南:从工具选型到容器避坑全解析

内存压力测试实战指南:从工具选型到容器避坑全解析

简介&#xff1a;一份内存压力测试工具memtester 4.1.2的源码压缩包&#xff0c;面向Linux系统管理员、运维人员及底层开发者&#xff0c;用于检测服务器或PC内存的稳定性与潜在错误&#xff0c;解决因内存位翻转、数据丢失或内存泄漏导致的系统崩溃、数据损坏等隐患。压缩包仅…

2026/10/4 21:56:06 阅读更多 →
Cursor插件四层架构:解决加载失败与中文支持实战指南

Cursor插件四层架构:解决加载失败与中文支持实战指南

1. 项目概述&#xff1a;从“plugins”标题看Cursor生态的底层逻辑与实操真相“plugins”这个词在Cursor语境下&#xff0c;绝不是简单的一个文件夹名或配置项。它直指当前AI编程工具最核心、也最容易被新手忽略的命脉——可扩展性架构。我用Cursor三年&#xff0c;从最早手动改…

2026/10/4 21:55:05 阅读更多 →
Unity3D嵌入WPF实战:窗口句柄、D3DImage纹理共享与视频流方案选型

Unity3D嵌入WPF实战:窗口句柄、D3DImage纹理共享与视频流方案选型

简介&#xff1a;面向需要在桌面应用中集成三维交互能力的开发者&#xff0c;这份资源围绕Unity3D嵌入WPF的实现流程&#xff0c;提供了从Unity场景设计、工程导出到WPF宿主集成的完整示例&#xff0c;覆盖了WindowsFormsHost控件承载渲染窗口、场景加载&#xff0c;以及Unity与…

2026/10/4 21:55:05 阅读更多 →
代码 Agent 自动处理 GitHub Issue 并生成 PR 的工程实践

代码 Agent 自动处理 GitHub Issue 并生成 PR 的工程实践

1. 为什么我要把 Issue 到 PR 这条链路交给代码 Agent第一次冒出“让代码 Agent 处理 GitHub Issue”这个念头&#xff0c;是因为我实在受够了那种机械重复的搬运工作。团队里每天都有新 Issue 进来&#xff0c;一半是拼写错误、空指针防护、日志格式不统一这类小修小补&#x…

2026/10/4 21:55:05 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 11:40:45 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 20:14:29 阅读更多 →