跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Spring AOP 核心概念与实战入门

Spring AOP 是 Spring 框架的核心特性之一,用于实现面向切面编程。通过动态代理技术,AOP 能在不修改源代码的情况下增强方法功能,如日志记录、性能监控等。结合代码示例,演示了如何引入依赖、编写切面类及配置通知,并分析了其在解耦、代码复用及系统维护方面的优势。

laoliangsh发布于 2026/3/15更新于 2026/6/1226 浏览
Spring AOP 核心概念与实战入门

Spring AOP 核心概念与实战入门

AOP(Aspect Oriented Programming,面向切面编程)是 Spring 框架的两大核心之一,另一个是 IoC。简单来说,AOP 是一种思想,旨在将那些与业务无关、却为业务模块所共同调用的逻辑(如事务管理、日志记录、性能监控等)封装起来,减少系统的重复代码,降低模块间的耦合度。

为什么需要 AOP?

在实际开发中,我们往往面临这样的场景:项目中有大量业务功能,某些接口执行效率较低,需要优化。第一步通常是定位耗时较长的方法,而统计每个方法的运行时间是一个典型需求。

如果不使用 AOP,我们需要在每个业务方法的前后手动添加记录开始和结束时间的代码。随着业务模块增多,这种重复工作会显著增加维护成本。AOP 的优势在于,它允许我们在不修改源代码的前提下,针对特定方法进行功能增强。这种非侵入式的解耦方式,正是 AOP 的核心价值所在。

实战:引入依赖与编写程序

1. 引入 AOP 依赖

在 pom.xml 中添加 Spring Boot 的 AOP 启动器依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 编写切面类 (Aspect)

接下来定义一个切面类,用于拦截目标方法并记录耗时。这里使用 @Around 环绕通知,它可以包裹目标方法的执行过程。

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@Aspect
public class AspectTest {

    /**
     * 记录方法耗时
     */
    @Around("execution(* com.wmh.springaop.controller.*.*(..))")
    public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
        // 记录方法执行开始时间
        long begin = System.currentTimeMillis();
        
        // 执行原始方法,这是关键步骤,必须调用 proceed() 才能继续后续逻辑
        Object result = pjp.proceed();
        
        // 记录方法执行结束时间
        long end = System.currentTimeMillis();
        
        // 输出耗时信息
        log.info(pjp.getSignature() + "执行耗时:{}ms", end - begin);
        return result;
    }
}

注意: 这里的切入点表达式 execution(* com.wmh.springaop.controller.*.*(..)) 表示拦截该包下所有 Controller 的所有方法。实际项目中应根据具体需求调整路径。

3. 目标控制器 (Controller)

为了验证效果,我们需要一个被拦截的目标类。

package com.wmh.springaop.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RequestMapping("/test")
@RestController
public class TestController {

    @RequestMapping("/t1")
    public String t1() {
        log.info("执行 t1 方法...");
        try {
            Thread.sleep(100); // 模拟耗时操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "t1";
    }
}

4. 运行结果

当访问 /test/t1 接口时,控制台会同时打印业务日志和切面记录的耗时日志。这证明了在不修改 TestController 源码的情况下,我们已经成功增强了其功能。

文章配图

关键注解解析

在上述代码中,有几个核心注解起到了决定性作用:

  • @Aspect: 标识该类为一个切面类,告诉 Spring 容器这是一个 AOP 组件。
  • @Around: 环绕通知,意味着通知逻辑会在目标方法执行前后都被触发。这是最强大的通知类型,可以控制是否执行目标方法以及修改返回值。
  • ProceedingJoinPoint.proceed(): 这是执行原始方法的关键。如果不调用此方法,目标方法将不会执行,相当于直接拦截了请求。

整个流程可以概括为三部分:方法执行前逻辑 -> 原始方法执行 -> 方法执行后逻辑。通过这种结构,我们可以灵活地插入各种横切关注点。

AOP 的主要优势

理解了基本用法后,我们再来看看 AOP 带来的核心价值:

  1. 关注点分离 将日志、安全、事务等非核心逻辑从业务代码中剥离,使业务逻辑更清晰,专注于核心功能实现。

  2. 代码重用 将通用的辅助功能封装为可重用的切面,避免在多个模块中重复编写相同代码,减少冗余。

  3. 系统可维护性增强 横切关注点集中在切面中管理,修改这些功能只需改动一处,降低了维护成本和引入新错误的风险。

  4. 灵活性提高 基于动态代理技术,可以在运行时动态地将切面应用到目标对象上。新增或移除切面无需修改现有业务逻辑。

  5. 易于测试 单元测试可以更聚焦于业务功能本身,因为非核心代码已被隔离。部分切面甚至可以在测试环境中被禁用或替换。

  6. 支持事务管理 Spring 的事务管理底层就是基于 AOP 实现的。通过声明式事务,开发者可以轻松定义哪些方法需要事务支持,无需在代码中混入复杂的事务处理逻辑。

通过上述示例,我们可以看到 Spring AOP 如何以简洁的方式解决复杂的横切问题。掌握这一机制,对于构建高质量、易维护的企业级应用至关重要。

目录

  1. Spring AOP 核心概念与实战入门
  2. 为什么需要 AOP?
  3. 实战:引入依赖与编写程序
  4. 1. 引入 AOP 依赖
  5. 2. 编写切面类 (Aspect)
  6. 3. 目标控制器 (Controller)
  7. 4. 运行结果
  8. 关键注解解析
  9. AOP 的主要优势
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 脉向AI|当豆包手机遭遇“全网封杀“:GUI Agent是通向AGI的必经之路吗?
  • STC32G12K128 指针强转实现 EEPROM 复杂数据类型存储
  • 网络安全自学入门指南:从零开始的学习路径与实战建议
  • Windows 安装 Neo4j 图数据库详细教程
  • VS Code + GitHub Copilot 避坑指南:从安装配置到最佳实践
  • Java 核心面试题与解析
  • 掌握大语言模型:语言理解与生成
  • 使用 Visual Studio 2026 简化 Git 工作流程
  • Windows 系统多硬盘切换引导盘设置指南
  • Flood Fill 算法实战:图像渲染与岛屿问题解析
  • 大语言模型入门指南:原理、类型与应用
  • Vivado 许可证获取、配置与管理指南
  • Web3.0 开发实践:核心概念与技术架构
  • VSCode 集成 Copilot 配置并使用 DeepSeek 模型
  • OpenClaw + Claude 搭建自动写作工作流实践
  • GitHub Copilot Pro 使用指南:模型选择与配额管理策略
  • 宇树 G1 机器人导航仿真:地图构建与参数配置实战
  • 基于 PSO-DWA 融合的无人机三维动态避障路径规划 (Matlab)
  • DeepSeek 在主流云电脑平台的部署与性能对比评测
  • Java 读取 Word 文档 (.doc/.docx) 实现方法

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online