news 2026/5/6 20:05:35

最近在刷牛客:使用Spring AOP实现性能监控时

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
最近在刷牛客:使用Spring AOP实现性能监控时

题目:4.使用Spring AOP实现性能监控时,下列哪种方式无法获取方法执行时间?

A在@Around增强中通过ProceedingJoinPoint.proceed()调用前后计算时间差

B在@AfterReturning增强中通过JoinPoint获取方法开始时间戳

C使用@Before记录开始时间并存入ThreadLocal,在@After中计算耗时

D通过实现MethodInterceptor接口在invoke方法中计算执行时间

项目目标

  • 使用 Spring Boot

  • 演示4 种 AOP 方式

  • 验证哪一种不能获取方法执行时间

  • 结构清晰,适合练习和面试


一、项目结构(强烈建议你照着建)

spring-aop-demo ├── pom.xml └── src └── main └── java └── com └── example └── aopdemo ├── AopDemoApplication.java ├── service │ └── UserService.java ├── aspect │ ├── TimeAspect.java │ └── TimeInterceptorConfig.java └── interceptor └── TimeMethodInterceptor.java

二、pom.xml(完整)

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.1</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>spring-aop-demo</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- AOP --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

三、启动类

package com.example.aopdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class AopDemoApplication { public static void main(String[] args) { SpringApplication.run(AopDemoApplication.class, args); } }

四、业务类(被代理对象)

package com.example.aopdemo.service; import org.springframework.stereotype.Service; @Service public class UserService { public void login() throws InterruptedException { Thread.sleep(300); // 模拟方法执行 System.out.println("执行 login 方法"); } }

五、AOP 切面(核心)

package com.example.aopdemo.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Aspect @Component public class TimeAspect { /* ========== A. @Around(能统计时间) ========== */ @Around("execution(* com.example.aopdemo.service..*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable { long start = System.currentTimeMillis(); Object result = pjp.proceed(); long end = System.currentTimeMillis(); System.out.println("[Around] 耗时:" + (end - start)); return result; } /* ========== B. @AfterReturning(不能统计时间) ========== */ @AfterReturning("execution(* com.example.aopdemo.service..*(..))") public void afterReturning(JoinPoint jp) { System.out.println("[AfterReturning] 无法获取开始时间"); } /* ========== C. @Before + @After + ThreadLocal(能统计时间) ========== */ private static final ThreadLocal<Long> TIME = ThreadLocal.withInitial(System::currentTimeMillis); @Before("execution(* com.example.aopdemo.service..*(..))") public void before() { TIME.set(System.currentTimeMillis()); } @After("execution(* com.example.aopdemo.service..*(..))") public void after() { long cost = System.currentTimeMillis() - TIME.get(); System.out.println("[Before+After] 耗时:" + cost); TIME.remove(); } }

六、MethodInterceptor 方式(能统计时间)

1. 拦截器

package com.example.aopdemo.interceptor; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class TimeMethodInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { long start = System.currentTimeMillis(); Object result = invocation.proceed(); long end = System.currentTimeMillis(); System.out.println("[MethodInterceptor] 耗时:" + (end - start)); return result; } }

2. 配置类

package com.example.aopdemo.aspect; import com.example.aopdemo.interceptor.TimeMethodInterceptor; import org.springframework.aop.framework.ProxyFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TimeInterceptorConfig { @Bean public ProxyFactoryBean userServiceProxy(UserService userService) { ProxyFactoryBean factory = new ProxyFactoryBean(); factory.setTarget(userService); factory.addAdvice(new TimeMethodInterceptor()); return factory; } }

七、测试方式(最简单)

启动项目后访问:

GET http://localhost:8080/test

或者直接写测试类:

@SpringBootTest class AopDemoApplicationTests { @Autowired private UserService userService; @Test void testAop() throws InterruptedException { userService.login(); } }

八、你运行后会看到类似输出

[Around] 耗时:302 [Before+After] 耗时:302 [MethodInterceptor] 耗时:301 [AfterReturning] 无法获取开始时间 执行 login 方法

✅ 一眼就能验证B 是错误的

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/6 20:02:32

Fan Control终极指南:5步打造完美的Windows风扇控制系统

Fan Control终极指南&#xff1a;5步打造完美的Windows风扇控制系统 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/…

作者头像 李华
网站建设 2026/5/6 20:00:31

请问天津水阀可以用吗

在阀门市场中&#xff0c;众多用户在选择产品时常常会有这样的疑问&#xff1a;天津水阀可以用吗&#xff1f;答案是肯定的。天津水阀机械有限公司作为一家集产品研发、设计、生产、销售、服务于一体的现代化阀门生产企业&#xff0c;有着诸多值得用户选择的优势。一、强大的企…

作者头像 李华
网站建设 2026/5/6 19:59:12

SILICON芯科 EFR32MG24A020F1024IM40-BR QFN40 无线收发芯片

1.功能列表 EFR32MG24的突出特性如下所示。 低功耗无线系统级芯片 高性能32位78MHzARMCortex-M33&#xff0c;配备DSP指 令和浮点单元&#xff0c;用于高效信号处理 最高1536kB闪存程序内存 最多256kB RAM数据存储 2.4GHz无线通信操作 用于AI/ML加速的矩阵向量处理器 无线性能 …

作者头像 李华
网站建设 2026/5/6 19:54:28

AI 英语伴学 APP的开发技术

构建一款商业级的 AI 英语伴学 APP&#xff0c;技术栈的选择不仅要满足高并发、高可用&#xff0c;更核心的是解决多模态音频流的极速响应&#xff08;低延迟&#xff09;以及教育场景的强控制&#xff08;不瞎聊、会纠错&#xff09;。以下是打造该 APP 核心五大模块及底层架构…

作者头像 李华
网站建设 2026/5/6 19:50:49

将 Hermes Agent 工具对接至 Taotoken 平台的具体配置步骤

将 Hermes Agent 工具对接至 Taotoken 平台的具体配置步骤 1. 准备工作 在开始配置前&#xff0c;请确保已具备以下条件&#xff1a; 有效的 Taotoken API Key&#xff08;可在 Taotoken 控制台创建&#xff09;目标模型 ID&#xff08;可在 Taotoken 模型广场查看&#xff…

作者头像 李华
网站建设 2026/5/6 19:48:22

ChineseSubFinder完整指南:3步打造智能字幕自动化系统

ChineseSubFinder完整指南&#xff1a;3步打造智能字幕自动化系统 【免费下载链接】ChineseSubFinder 自动化中文字幕下载。字幕网站支持 shooter、xunlei、arrst、a4k、SubtitleBest 。支持 Emby、Jellyfin、Plex、Sonarr、Radarr、TMM 项目地址: https://gitcode.com/gh_mi…

作者头像 李华