实用指南:12. AOP(记录日志)

news/2026/1/21 19:25:08/文章来源:https://www.cnblogs.com/gccbuaa/p/19513835

AOP 学习笔记

一、AOP 基础认知

1. 什么是 AOP

  • 定义:AOP(Aspect Oriented Programming)即面向切面编程,核心是面向特定方法编程,将重复逻辑与业务逻辑分离,实现功能增强。
  • 本质:不修改原始业务代码,通过动态代理技术对目标方法进行增强,解决代码重复、侵入性强的问题。

2. AOP 核心优势

3. 核心概念

概念定义
连接点(JoinPoint)可被 AOP 控制的方法(如业务层所有方法),封装了方法执行时的相关信息
通知(Advice)抽取的重复逻辑(共性功能),体现为具体方法(如计时、日志记录)
切入点(PointCut)匹配连接点的条件(通过表达式描述),决定通知应用于哪些方法
切面(Aspect)通知与切入点的对应关系(通知+切入点),所在类为切面类(@Aspect 标识)
目标对象(Target)通知所应用的原始业务对象
代理对象Spring AOP 底层通过动态代理生成,用于增强目标对象的方法

4. 底层原理

Spring AOP 基于动态代理技术实现:程序运行时自动为目标对象生成代理对象,在代理对象中嵌入通知逻辑,实现对原始方法的增强。

二、AOP 入门实战

1. 需求

统计部门管理业务层方法的执行耗时。

2. 实现步骤

(1)导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
(2)编写切面类
@Component
@Aspect // 标识为切面类
@Slf4j
public class RecordTimeAspect {
// 环绕通知 + 切入点表达式(匹配目标方法)
@Around("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))")
public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
// 1. 记录开始时间
long begin = System.currentTimeMillis();
// 2. 执行原始业务方法
Object result = pjp.proceed();
// 3. 记录结束时间并计算耗时
long end = System.currentTimeMillis();
log.info("方法执行耗时: {}毫秒", end - begin);
// 4. 返回原始方法结果
return result;
}
}
(3)测试效果

启动服务后,调用业务接口,控制台会输出对应方法的执行耗时。

3. 常见应用场景

三、AOP 进阶知识

1. 通知类型

Spring AOP 提供 5 种通知类型,覆盖方法执行的不同阶段:

通知注解执行时机注意事项
@Around(环绕通知)目标方法执行前 + 执行后需调用 proceed() 执行原始方法,必须返回结果
@Before(前置通知)目标方法执行前无返回值,不能阻止目标方法执行
@After(后置通知)目标方法执行后(无论是否抛出异常)无返回值
@AfterReturning目标方法正常执行完成后(无异常)可获取方法返回值
@AfterThrowing目标方法抛出异常后可获取异常信息
通知执行顺序(无异常情况)

@Around(前)@Before → 目标方法 → @Around(后)@AfterReturning@After

异常情况

@Around(前)@Before → 目标方法(抛异常) → @AfterThrowing@After@Around 后续逻辑不执行)

2. 切入点表达式

用于描述需要匹配的目标方法,核心有 2 种形式:

(1)execution 表达式(常用)
(2)@annotation 表达式(灵活匹配)

通过自定义注解标记目标方法,适合无规则的方法匹配:

  1. 定义自定义注解:
    @Target(ElementType.METHOD) // 仅作用于方法
    @Retention(RetentionPolicy.RUNTIME) // 运行时生效
    public @interface LogOperation {}
  2. 在目标方法上添加注解:
    @Service
    public class DeptServiceImpl implements DeptService {
    @Override
    @LogOperation // 标记需要增强的方法
    public void delete(Integer id) {
    deptMapper.delete(id);
    }
    }
  3. 切面类中引用注解:
    @Before("@annotation(com.itheima.anno.LogOperation)")
    public void before(JoinPoint joinPoint) {
    log.info("前置通知:记录操作日志");
    }
切入点表达式复用

使用 @Pointcut 抽取公共表达式,避免重复编写:

@Aspect
@Component
public class MyAspect {
// 抽取公共切入点表达式
@Pointcut("execution(* com.itheima.service.*.*(..))")
private void pt() {}
// 引用公共表达式
@Before("pt()")
public void before() {
log.info("前置通知...");
}
}

3. 通知顺序控制

当多个切面类匹配同一个目标方法时,通过以下方式控制执行顺序:

  1. 默认规则:按切面类名的字母顺序排序(前置通知:字母靠前先执行;后置通知:字母靠前后执行)
  2. @Order 注解(推荐):在切面类上添加 @Order(数字),数字越小,优先级越高
    @Aspect
    @Component
    @Order(1) // 优先级高于 Order(2) 的切面
    public class MyAspect1 { ... }

四、AOP 案例:操作日志记录

1. 需求

记录系统中增删改接口的操作日志,包含:操作人、操作时间、类名、方法名、参数、返回值、执行时长,存入数据库。

2. 实现步骤

(1)准备工作
  1. 数据库表设计:
    create table operate_log(
    id int unsigned primary key auto_increment comment 'ID',
    operate_emp_id int unsigned comment '操作人ID',
    operate_time datetime comment '操作时间',
    class_name varchar(100) comment '操作的类名',
    method_name varchar(100) comment '操作的方法名',
    method_params varchar(1000) comment '方法参数',
    return_value varchar(2000) comment '返回值',
    cost_time int comment '方法执行耗时(ms)'
    ) comment '操作日志表';
  2. 实体类 OperateLog + Mapper 接口(提供 insert 方法)
(2)编码实现
  1. 自定义注解 @LogOperation(标记需要记录日志的接口方法)
  2. 切面类实现:
    @Aspect
    @Component
    public class OperationLogAspect {
    @Autowired
    private OperateLogMapper operateLogMapper;
    @Around("@annotation(com.itheima.anno.LogOperation)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    // 1. 记录开始时间
    long startTime = System.currentTimeMillis();
    // 2. 执行原始方法
    Object result = joinPoint.proceed();
    // 3. 计算耗时
    long costTime = System.currentTimeMillis() - startTime;
    // 4. 构建日志对象
    OperateLog log = new OperateLog();
    log.setOperateEmpId(CurrentHolder.getCurrentId()); // 从 ThreadLocal 获取当前登录人ID
    log.setOperateTime(LocalDateTime.now());
    log.setClassName(joinPoint.getTarget().getClass().getName()); // 目标类名
    log.setMethodName(joinPoint.getSignature().getName()); // 目标方法名
    log.setMethodParams(Arrays.toString(joinPoint.getArgs())); // 方法参数
    log.setReturnValue(result.toString()); // 返回值
    log.setCostTime(costTime);
    // 5. 保存日志到数据库
    operateLogMapper.insert(log);
    return result;
    }
    }
  3. 在 Controller 层增删改方法上添加 @LogOperation 注解

3. 关键技术:ThreadLocal 共享登录信息

  • 作用:在同一线程(同一请求)中共享数据(如当前登录人ID),实现线程隔离
  • 工具类实现
    public class CurrentHolder {
    private static final ThreadLocal<Integer> CURRENT_LOCAL = new ThreadLocal<>();// 设置当前登录人IDpublic static void setCurrentId(Integer empId) {CURRENT_LOCAL.set(empId);}// 获取当前登录人IDpublic static Integer getCurrentId() {return CURRENT_LOCAL.get();}// 移除数据(避免内存泄漏)public static void remove() {CURRENT_LOCAL.remove();}}
  • 使用场景:在 Token 过滤器中解析登录人ID并存入 ThreadLocal,在 AOP 中直接获取。

四、核心总结

  1. AOP 核心思想是分离共性逻辑与业务逻辑,通过切面类统一管理增强功能
  2. 5 种通知类型覆盖方法执行全生命周期,@Around 功能最强大(可控制原始方法执行)
  3. 切入点表达式两种形式:execution(按方法签名匹配)、@annotation(按注解匹配)
  4. 多切面执行顺序通过 @Order 控制,数字越小优先级越高
  5. 实际开发中常用 AOP 实现日志、权限、事务等非业务功能,提高代码复用性和可维护性

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

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

相关文章

springboot基于Java的外卖管理系统设计开发实现

背景与意义 外卖行业的快速发展促使餐饮企业需要高效的管理系统来应对订单处理、配送调度、用户反馈等复杂需求。传统人工管理方式效率低下&#xff0c;难以满足现代外卖业务的高并发、实时性要求。SpringBoot框架因其简化配置、快速开发的特点&#xff0c;成为构建外卖管理系…

2026主管护师护理学怎么备考,全流程指南稳步通关不跑偏

前言:主管护师护理学考试考点繁杂,多数考生为在职人员,时间碎片化问题突出,易陷入备考盲目、效率低下的困境。想要高效通关,需搭建科学的备考框架,遵循循序渐进的流程,准确匹配备考各阶段需求。本文梳理主管护师…

ai做PPT正确打开方式:选对工具+用对方法,3分钟搞定专业演示

市面上现在也是涌现出太多AIPPT产品&#xff0c;大家往往陷入选择困难&#xff0c;究竟哪款真正适配需求&#xff1f;本文选取了3款AI PPT工具进行讲解。1、AI PPT国内主流的AI演示文稿工具&#xff0c;提供“主题生成、文档导入、PPT美化”三种核心模式&#xff0c;支持标题和…

谷歌发布AI广告与分析顾问:是SEO革命性产品,还是未来可期?

谷歌正在向其广告和分析生态系统中&#xff0c;注入一股前所未有的AI力量。其即将推出两款基于其最新Gemini模型构建的、全新的AI助手——广告顾问和分析顾问。从12月初开始&#xff0c;这两款工具将陆续向所有英语地区的Google Ads和Google Analytics账户开放。谷歌的愿景是&a…

深圳昊客/百度竞价开户推广代运营服务商:推荐排名前5的公司

深圳企业做百度推广,如何选择靠谱的代运营服务商? 在竞争激烈的数字营销环境中,越来越多深圳中小企业开始借助百度竞价(SEM)获取精准客户。但不少企业主发现:广告费花了不少,有效咨询却寥寥无几。问题往往不在平…

git使用--depth参数参数快速拉取分支代码后无法切换到其他分支解决办法

我们经常有被催得比较急的项目&#xff0c;早上到我们手&#xff0c;晚上就要求要的&#xff0c;如果我们本地没有代码那就要克隆一份完整代码过来做需求&#xff0c;但是完整克隆一份好几百G的代码下来是相当耗时的&#xff0c;那么我们有没有一种方法能快速拉取一份代码做客制…

springboot基于java的网吧管理系统设计实现

网吧管理系统设计的背景随着互联网的普及和网络娱乐需求的增长&#xff0c;网吧作为提供上网服务的场所&#xff0c;其管理复杂度日益增加。传统的手工记录和简单的电子表格管理方式已无法满足现代网吧运营的需求。会员管理、设备维护、计费统计等环节需要更高效、自动化的解决…

金华宠物医院优选推荐,2026年宠主好评TOP榜单,猫咪体检/宠物神经外科/宠物眼科/母猫绝育,宠物医生排名前十

随着宠物经济持续升温,宠物医疗行业迎来快速发展期。据《2025年中国宠物行业白皮书》显示,我国宠物医疗市场规模已突破800亿元,年复合增长率达18%,但行业仍存在设备参差不齐、专科细分不足、服务透明度低等痛点。在…

Mysql优化笔记 - 倾听

1. 全文索引 当字段的值存在 A,B,C 时,参数是个集合,要进行多个值匹配时,如果使用 like or 的方式,直接会变成全表扫描,这个时候可以使用 全文索引 a. 添加索引ALTER TABLE table_name ADD FULLTEXT INDEX index_…

springboot基于Java的诊所管理系统设计实现

背景分析 医疗行业信息化需求日益增长&#xff0c;传统纸质记录和手工管理方式效率低下&#xff0c;易出错。诊所作为基层医疗机构&#xff0c;亟需通过数字化系统优化患者管理、药品库存、财务统计等核心业务流程。Java技术栈凭借稳定性、跨平台性及丰富的生态&#xff0c;成…

为应对“差评勒索”,谷歌上月推出的负面评论敲诈举报表单似乎非常有效

在本地商业的数字战场上&#xff0c;谷歌商业资料的评论区&#xff0c;早已成为兵家必争之地。 它被视为用户口碑最真实的映照&#xff0c;是商家信誉的晴雨表。 当然&#xff0c;有利益的地方就会有不为人知的阴暗面。 一种新型的、有组织的恶意行为——负面评论敲诈&#…

2024年提示工程热点:生命周期管理的4个关键进化方向

2024年提示工程热点:生命周期管理的4个关键进化方向 一、引入与连接 引人入胜的开场 想象一下,在科技的浩瀚宇宙中,有一颗闪耀的星星叫做提示工程。它就像是一位神奇的魔法师,能够让计算机理解我们人类的语言,并按照我们的要求完成各种任务。从智能客服与我们流畅对话,…

挑战Sora!以色列独角兽Lightricks发布LTX-2

首个非对称双流架构,1秒极速有声生成!在多模态生成领域, 打破视觉与听觉模态的物理壁垒、实现跨感官信息的有机融合与“感官统一” ,是当前学界与工业界亟待解决的核心挑战。长期以来,有声视频生成(Sounding Vid…

2025年AI超级员工公司综合排名权威发布,AI企业员工/AI智能员工/AI超级员工/AI员工品牌口碑排行

行业格局深度解析 随着人工智能技术在各行业的深入应用,AI超级员工市场呈现出蓬勃发展的态势。据最新行业数据显示,2024年中国AI超级员工市场规模已达百亿级别,预计2025年将实现40%以上的增长。在这一快速发展的赛道…

springboot基于java零售与仓储管理系统的设计与实现

背景分析 零售与仓储管理系统在传统行业中常面临效率低、数据孤岛、人工错误率高的问题。随着电商与新零售的崛起&#xff0c;企业对实时库存管理、供应链协同、数据分析的需求激增。Java技术栈凭借其稳定性、跨平台性及丰富的开源生态&#xff08;如SpringBoot、MyBatis&…

一加7刷入twrp

一加7刷入twrp./fastboot set_active b .\fastboot flash boot_b .\twrp-3.7.1_12-0-guacamole.imgfastboot reboot recovery 进入twrp后 mount中禁用启动mtp,将ota刷机包上传到手机, 双清 在install安装ota刷人包 …

如何解析iOS崩溃日志:从获取到符号化分析 - 指南

如何解析iOS崩溃日志:从获取到符号化分析 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas",…

告别噪音与回音!WX-0813 AI 语音处理模组,重塑音频通话体验

在会议设备、智能家居对讲、车载蓝牙通话等场景中&#xff0c;噪音和回音一直是影响音频体验的 “老大难” 问题。风扇声、空调声会干扰拾音清晰度&#xff0c;喇叭与麦克风近距离摆放产生的回音会让通话双方苦不堪言。 今天要给大家推荐一款能一站式解决这些问题的硬核产品 —…

深圳昊客网络|百度推广开户竞价代运营公司/服务商:推荐排名前十的机构

在2026年,深圳企业主若想通过百度竞价(SEM)高效获客,早已不能靠“砸钱”取胜。随着AI技术全面渗透数字营销、B2B采购决策链日益复杂,选对一家真正懂行业、敢为效果负责的代运营服务商,比多投10万元广告费更重要。…

告别玄学Prompt!Agent Skills让AI Agent真正干活,收藏级教程

Agent Skills是一套"教Agent怎么做事"的标准化技能说明书&#xff0c;介于Prompt和Tool之间&#xff0c;具有明确使用场景、固定执行流程和稳定输出标准。它解决了Prompt无法复用和Tool缺乏流程指导的问题&#xff0c;通过渐进式加载机制节省Token&#xff0c;让Agen…