网站设计基础知识,网站怎么做网络推广,张家港注册公司流程和费用,数字广东网络建设有限公司招聘Spring AOP 中记录日志
使用 AOP 和 Spring 提供的 RequestContextHolder 在通知中记录 HTTP 请求相关日志。以下是进阶添加日志功能的完整例子和说明。 完整示例
1. 切面类实现
Aspect
Component
public class LogAspect {Around(annotation(log)) // 拦截所有…Spring AOP 中记录日志
使用 AOP 和 Spring 提供的 RequestContextHolder 在通知中记录 HTTP 请求相关日志。以下是进阶添加日志功能的完整例子和说明。 完整示例
1. 切面类实现
Aspect
Component
public class LogAspect {Around(annotation(log)) // 拦截所有标注 Log 的方法public Object logExecution(ProceedingJoinPoint joinPoint, Log log) throws Throwable {// 获取 HttpServletRequest 对象ServletRequestAttributes attributes (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request attributes.getRequest();// 提取请求信息String url request.getRequestURL().toString();String method request.getMethod();String ip request.getRemoteAddr();String params request.getQueryString();// 方法名和参数String methodName joinPoint.getSignature().getName();Object[] args joinPoint.getArgs();// 记录日志 - 方法执行前System.out.println(请求 URL: url);System.out.println(HTTP 方法: method);System.out.println(请求 IP: ip);System.out.println(请求参数: params);System.out.println(方法名称: methodName);System.out.println(方法参数: Arrays.toString(args));long startTime System.currentTimeMillis();// 执行目标方法Object result;try {result joinPoint.proceed(); // 执行被拦截的方法} catch (Throwable ex) {// 异常处理System.err.println(方法执行异常: methodName , 异常信息: ex.getMessage());throw ex;}long timeTaken System.currentTimeMillis() - startTime;// 记录日志 - 方法执行后System.out.println(方法执行完成: methodName , 返回值: result , 耗时: timeTaken ms);return result; // 返回目标方法的执行结果}
}2. 自定义注解
在需要记录日志的方法上标注自定义注解 Log:
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
public interface Log {String value() default ;
}3. 控制器示例
在控制器方法上使用 Log 注解:
RestController
RequestMapping(/api)
public class TestController {GetMapping(/test)Log(测试日志记录)public String testLog(RequestParam String input) {if (error.equals(input)) {throw new RuntimeException(模拟异常);}return Hello, input;}
}日志输出示例
正常请求
访问 http://localhost:8080/api/test?inputworld 记录如下:
请求 URL: http://localhost:8080/api/test
HTTP 方法: GET
请求 IP: 127.0.0.1
请求参数: inputworld
方法名称: testLog
方法参数: [world]
方法执行完成: testLog, 返回值: Hello, world, 耗时: 10ms异常请求
访问 http://localhost:8080/api/test?inputerror 记录如下:
请求 URL: http://localhost:8080/api/test
HTTP 方法: GET
请求 IP: 127.0.0.1
请求参数: inputerror
方法名称: testLog
方法参数: [error]
方法执行异常: testLog, 异常信息: 模拟异常关键点解析
1. 为什么使用 RequestContextHolder?
HttpServletRequest 是与线程绑定的通过 RequestContextHolder 可以方便地在 AOP 切面中获取当前请求的 HttpServletRequest 对象。
2. 日志内容可记录什么?
请求的 URL (request.getRequestURL())HTTP 方法 (request.getMethod())客户端 IP 地址 (request.getRemoteAddr())请求参数 (request.getQueryString())被拦截方法的名称和参数 (joinPoint.getSignature() 和 joinPoint.getArgs())方法执行耗时。
3. 异常处理
在 catch 块中记录方法执行时报出的异常信息以便后续排查问题。 总结
通过 AOP 和 RequestContextHolder 在通知中进行统一的日志记录便于跟踪和排查 HTTP 请求相关的信息。Around 通知允许在方法执行前后和异常情况下插入日志逻辑适用于统一的日志记录场景。