第一步引入必要的依赖

<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.*;
/**
* @author zhr_java@163.com
* @date 2022/3/29 20:56
*/
@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;
/**
* @author zhr_java@163.com
* @date 2022/3/29 20:59
*/
@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) {
// get parameter names
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;
/**
* @author zhr_java@163.com
* @date 2022/3/29 20:50
*/
@RestController
@RequestMapping("/person")
public class PersonController {
//在此处加上你自定义的注解(@LogNotice)
@LogNotice
@GetMapping("get_person")
public String getPerson(Integer numbers) {
return "123";
}
}

第五步测试

在这里插入图片描述

在这里插入图片描述

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

posted on   张伯灵  阅读(78)  评论(0编辑  收藏  举报
编辑推荐:
· 基于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)



点击右上角即可分享
微信分享提示