第一步引入必要的依赖
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-web</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-devtools</artifactId> |
| <scope>runtime</scope> |
| <optional>true</optional> |
| </dependency> |
| <dependency> |
| <groupId>org.projectlombok</groupId> |
| <artifactId>lombok</artifactId> |
| <optional>true</optional> |
| </dependency> |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-test</artifactId> |
| <scope>test</scope> |
| </dependency> |
| <dependency> |
| <groupId>org.springframework</groupId> |
| <artifactId>spring-aop</artifactId> |
| <version>5.3.15</version> |
| </dependency> |
| <dependency> |
| <groupId>org.aspectj</groupId> |
| <artifactId>aspectjweaver</artifactId> |
| <version>1.9.2</version> |
| </dependency> |
第二步创建自定义日志注解类
实际上可以对注解添加一个业务类型参数表示日志的类型:新、删、改、查
| package com.example.aop.log.annotion; |
| |
| import java.lang.annotation.*; |
| |
| |
| |
| |
| |
| @Inherited |
| @Target({ElementType.METHOD}) |
| @Retention(value = RetentionPolicy.RUNTIME) |
| @Documented |
| public @interface LogNotice {} |
| |
第三步切面设计,扫描上面的注解
此处实际上还可以根据注解里面的参数来判断业务日志的类型:新、删、改、查
| package com.example.aop.log.aop; |
| |
| import org.aspectj.lang.ProceedingJoinPoint; |
| import org.aspectj.lang.Signature; |
| import org.aspectj.lang.annotation.Around; |
| import org.aspectj.lang.annotation.Aspect; |
| import org.aspectj.lang.annotation.Pointcut; |
| import org.aspectj.lang.reflect.MethodSignature; |
| import org.springframework.core.DefaultParameterNameDiscoverer; |
| import org.springframework.stereotype.Component; |
| |
| import java.lang.reflect.Method; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| |
| |
| |
| |
| @Aspect |
| @Component |
| public class LogAspect { |
| |
| |
| @Pointcut("@annotation(com.example.aop.log.annotion.LogNotice)") |
| public void doLog() {} |
| |
| @Around("doLog()") |
| public Object insertLog(ProceedingJoinPoint joinPoint) throws Throwable { |
| Object object = joinPoint.proceed(); |
| try { |
| HashMap paramsMap; |
| Signature signature = joinPoint.getSignature(); |
| Method method = ((MethodSignature) signature).getMethod(); |
| String methodName = method.getName(); |
| String className = method.getDeclaringClass().getName(); |
| paramsMap = (HashMap) getParams(joinPoint, method); |
| |
| System.out.println( |
| "methodName: " + methodName + "; className: " + className + "; paramsMap:" + paramsMap); |
| |
| } catch (Exception e) { |
| |
| } |
| |
| |
| return object; |
| } |
| |
| private Map<String, Object> getParams(ProceedingJoinPoint joinPoint, Method method) { |
| |
| String[] parameterNames = new DefaultParameterNameDiscoverer().getParameterNames(method); |
| Object[] args = joinPoint.getArgs(); |
| Map<String, Object> params = new HashMap<>(8); |
| if (parameterNames != null && parameterNames.length != 0) { |
| for (int i = 0; i < parameterNames.length; i++) { |
| params.put(parameterNames[i], args[i]); |
| } |
| } |
| return params; |
| } |
| } |
| |
第四步把自定义的注解放到你的接口上面
| package com.example.demo.controller; |
| |
| import com.example.aop.log.annotion.LogNotice; |
| import org.springframework.web.bind.annotation.GetMapping; |
| import org.springframework.web.bind.annotation.RequestMapping; |
| import org.springframework.web.bind.annotation.RestController; |
| |
| |
| |
| |
| |
| @RestController |
| @RequestMapping("/person") |
| public class PersonController { |
| |
| |
| @LogNotice |
| @GetMapping("get_person") |
| public String getPerson(Integer numbers) { |
| return "123"; |
| } |
| } |
| |
第五步测试


关注我的公众号SpaceObj 领取idea系列激活码

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)