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

软考高级系统架构师之Spring AOP篇

⚡ Spring AOP 核心导读

Spring AOP(Aspect-Oriented Programming)—— Spring 框架的核心模块之一,通过动态代理运行时将横切关注点(日志、事务、权限等)无侵入地织入业务方法,是 OOP 的有力补充。

  • 🧩分离关注点:业务逻辑与系统服务解耦
  • 🚀运行时织入:基于 JDK/CGLIB 动态代理,无需修改源码
  • 🎯方法级拦截:支持 5 种通知类型,精准控制执行时机
  • 🔧注解驱动@Aspect+@Pointcut极简配置,与 Spring Boot 无缝集成

💡 一句话:Spring AOP = 动态代理 + 切点表达式 + 通知,让你在不入侵业务代码的前提下,统一处理日志、事务、权限等“横切”逻辑。


系统架构师学习平台(点击这里进入)

📚 一、AOP 核心术语(必须掌握)

术语英文通俗解释类比
切面Aspect横切关注点的模块化单元 = 切入点 + 通知如“日志模块”、“事务模块”
连接点Join Point程序执行中所有可能被拦截的点(Spring 中仅指方法执行)所有路口
切入点Pointcut通过表达式精准匹配出来的实际拦截点设有红绿灯的路口
通知Advice在特定切入点执行的增强代码,定义何时 + 做什么红绿灯规则(停/行)
目标对象Target被增强的原始业务对象被管理的车辆
代理对象ProxyAOP 框架动态创建的对象,包含增强逻辑交警(指挥车辆)
织入Weaving将切面应用到目标对象并生成代理的过程安装交通系统的动作
引入Introduction动态为现有类添加新方法/属性给车辆加装新设备

🧭 二、五种通知类型(Advice)—— 拦截时机的艺术

通知类型注解执行时机典型用途
前置通知@Before目标方法执行之前参数校验、操作日志、权限预检
后置通知@After目标方法执行之后(无论是否异常)释放资源、关闭连接
返回通知@AfterReturning目标方法正常返回后(可获取返回值)记录响应数据、缓存更新
异常通知@AfterThrowing目标方法抛出异常统一异常捕获、错误告警
环绕通知@Around包围目标方法,可控制是否执行及参数返回值性能监控、事务管理、重试机制

⚠️ 原则:能用弱类型通知就别用环绕通知@Around最强大但最容易出错,需手动proceed())。


🎯 三、切点表达式(Pointcut)—— 精准定位的艺术

Spring AOP 采用AspectJ 切点表达式,最常用的是execution

基本语法
execution(修饰符? 返回类型 类全限定名.方法名(参数) 异常?)
常见示例
表达式示例含义
execution(* com.example.service.*.*(..))匹配 service 包下所有类的所有方法
execution(public * com.example.service.UserService.*(..))匹配 UserService 的 public 方法
execution(* com.example.service..*.*(..))匹配 service 包及子包所有方法
execution(* find*(..))匹配所有以find开头的方法
execution(* com.example.service.UserService.findUser(Long, ..))匹配第一个参数为 Long 的 findUser 方法
常用切点指示符(PCD)

⚙️ 四、实现原理 —— JDK 动态代理 vs CGLIB

Spring AOP 根据目标类是否实现接口,自动选择代理机制:

代理方式适用场景实现机制特点
JDK 动态代理目标类实现了接口java.lang.reflect.Proxy+InvocationHandler基于接口,轻量,JDK 原生
CGLIB 代理目标类未实现接口通过字节码技术生成子类(继承)不需要接口,但不能代理final方法

🚨 注意:Spring AOP只支持方法级连接点(无法拦截字段访问/构造器执行),这是由动态代理的天然限制决定的。


🧩 五、配置方式(注解驱动为主流)

1. 引入依赖(Spring Boot)
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
2. 启用 AOP
3. 编写切面(示例代码)
@Component@Aspect@Slf4jpublicclassLoggingAspect{// 1. 定义切入点(复用)@Pointcut("execution(* com.example.service.*.*(..))")publicvoidserviceLayer(){}// 2. 前置通知@Before("serviceLayer()")publicvoidlogBefore(JoinPointjp){log.info("调用方法:{},参数:{}",jp.getSignature().getName(),jp.getArgs());}// 3. 环绕通知(性能监控)@Around("serviceLayer()")publicObjectmeasureTime(ProceedingJoinPointpjp)throwsThrowable{longstart=System.currentTimeMillis();Objectresult=pjp.proceed();// 执行目标方法longcost=System.currentTimeMillis()-start;log.info("方法 {} 耗时 {} ms",pjp.getSignature().getName(),cost);returnresult;}}

📌 也可使用 XML 配置(现不常用),注解方式已主导。


🧪 六、实际落地场景(真实项目必备)

场景通知类型建议说明
操作日志记录@Before+@AfterReturning记录请求参数、响应结果、操作人
声明式事务管理@AroundSpring@Transactional底层基于 AOP
权限校验(RBAC)@Before方法执行前检查当前用户是否有权访问
接口耗时监控@Around统计慢接口,上报监控系统
统一异常处理@AfterThrowing捕获业务异常,封装成统一返回格式
缓存管理(@Cacheable)@Around方法执行前查缓存,执行后更新缓存
数据脱敏/加密@AfterReturning对返回的敏感字段(手机号、身份证)脱敏
重试机制@Around方法失败后自动重试(如调用外部 API)

🔍 七、Spring AOP 与 AspectJ 对比

维度Spring AOPAspectJ
织入时机运行时(动态代理)编译时 / 类加载时(字节码增强)
连接点范围仅方法执行方法、字段、构造器、静态初始化等
性能有代理开销(每次方法调用都走代理)无运行时开销(直接执行增强后的字节码)
易用性简单,与 Spring 无缝集成需要独立编译器/编织器,较复杂
适用场景大多数企业级应用(Web/微服务)对性能极致要求或需要细粒度拦截(如框架开发)

💡 实际生产中90% 场景使用 Spring AOP 就足够,除非你需要拦截字段访问或追求极致性能。


⚠️ 八、常见坑点 & 注意事项

问题原因解决方案
同一个类中方法调用不生效内部调用走this而非代理对象① 注入自身 Bean 调用;② 使用AopContext.currentProxy()
静态方法无法拦截代理无法覆盖静态方法改用 AspectJ 或手动调用
final方法无法被 CGLIB 代理CGLIB 通过继承,final方法不可覆写避免在代理类中使用final方法
循环依赖问题AOP 代理可能引发循环依赖使用@Lazy或设计上解耦
切面执行顺序混乱多个切面优先级未指定使用@Order注解或实现Ordered接口

📌 九、速记汇总·一图流

🔥总结:Spring AOP 通过运行时动态代理,把日志、事务等横切逻辑从业务代码中抽离,极大提升代码的复用性和可维护性。它与 Spring 生态天然融合,是每个后端开发者必须熟练掌握的利器。牢记:切点定位 + 通知织入 = 优雅解耦

适用场景:Web 层请求日志、Service 层事务管理、DAO 层异常转换、任意需要统一增强的业务模块。

http://www.jsqmd.com/news/1145245/

相关文章:

  • Python开发中的项目结构:如何组织代码更清晰
  • 单目稠密SLAM多机协同系统:面向GPS拒止环境的鲁棒实时建图
  • 从 Spring Boot 到 NestJS:项目快速上手指南
  • 2026微信商城搭建有哪些平台
  • 计算机毕业设计之基于web的曙光社区生鲜团购平台
  • TRAE SOLO:任务原生执行器与智能工作流操作系统
  • X-Content-Type-Options 实战配置:Nginx/Apache/Express 3种服务器完整指南
  • Ubuntu service开机自启设置
  • 行业案例拆解:RFID技术在餐饮行业连锁品牌应用案例拆解!
  • linux代码同步git仓库
  • Salesforce 收购 Informatica,可信上下文成企业 AI 关键要素!
  • 亿问 Data Agent 智能问数板块核心算法解析:语义收敛,问数可信
  • 2026抖音智能AI客服系统推荐:5大主流工具横评与选型指南
  • 这台扁平如盘的电机,正在同时改变机器人、超跑和飞行器
  • 海芯智训:跨越AI落地鸿沟,以实战交付重塑企业数智化生产力
  • 2026年Agent就业真相:高薪岗位都在抢什么人?
  • 2026无线充选购终极清单!桌面、车载、便携、磁吸,认准Qi认证零踩坑
  • AI助力自闭症儿童沟通:从专属工具到产品雏形,改变孩子生活!
  • 2026小程序商城平台哪家强
  • jumpserver堡垒机部署手册
  • OpenCore Legacy Patcher完全指南:让老款Mac免费升级最新macOS的终极方案
  • 数据库架构演进之路:从 MySQL 到 TiDB
  • ChatGPT品牌优化怎么做?从内容到渠道的落地观察
  • AI Agent爆了!10分钟搞定销售报告,背后原理全揭秘!你离智能体专家只差这一篇!
  • Vite 生产构建:Tree Shaking 失效的五个隐蔽场景
  • Anthropic论文揭秘Claude模型:J-space类似人脑结构,离AI“意识”还有多远?
  • 2026年生成式引擎优化(GEO)服务商权威评测与头部GEO公司推荐排名
  • 孩子书桌用什么灯好?盘点护眼效果好的护眼台灯,品质过硬!
  • 如何用 ClaudeAPI 整理区域市场报告并提取成交趋势
  • GPT-4 Turbo API 成本分析:输入/输出价格下调 3-5 倍,开发者如何规划预算?