Spring Aspect编程中,Spring切面包含通知和切点,通知和切点分别定义了在何时何处执行切面逻辑。
其中,Spring定义了五种不同类型的通知:
-
Before(目标方法执行前)
-
After(目标方法执行后,不关注执行结果)
-
After-returning(目标方法执行后,返回通知)
-
After-throwing(目标方法抛出异常后)
-
Around(目标方法执行前后、异常)
Spring切点,通过匹配规则查找合适的连接点,AOP会在这些连接点上织入通知
本文仅关注@Around,通过切面逻辑并在其中添加Log或其他方式,帮助我们快速定位异常点,方便系统监控和bug排查,并通过下方代码展示其使用方式
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66@Aspect @Component @Slf4j public class ControllerLogAop { @Pointcut("execution(* *..*.*.controller..*.*(..))") public void controller() { } @Around("controller()") public Object controller(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { // 获取类名 String className = proceedingJoinPoint.getTarget().getClass().getSimpleName(); // 获取方法名 String methodName = proceedingJoinPoint.getSignature().getName(); // 获取方法的参数 Object[] args = proceedingJoinPoint.getArgs(); // 获取controller的请求属性数据 ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = Objects.requireNonNull(requestAttributes).getRequest(); printRequestLog(request, className, methodName, args); long start = System.currentTimeMillis(); // 继续执行方法逻辑 Object returnObj = proceedingJoinPoint.proceed(); printResponseLog(request, className, methodName, returnObj, System.currentTimeMillis() - start); return returnObj; } private void printRequestLog(HttpServletRequest request, String clazzName, String methodName, Object[] args) throws JsonProcessingException { log.debug("Request URL: [{}], URI: [{}], Request Method: [{}], IP: [{}]", request.getRequestURL(), request.getRequestURI(), request.getMethod(), ServletUtil.getClientIP(request)); if (args == null || !log.isDebugEnabled()) { return; } boolean shouldNotLog = false; for (Object arg : args) { if (arg == null || arg instanceof HttpServletRequest || arg instanceof HttpServletResponse || arg instanceof MultipartFile || arg.getClass().isAssignableFrom(MultipartFile[].class)) { shouldNotLog = true; break; } } if (!shouldNotLog) { String requestBody = JsonUtils.objectToJson(args); log.debug("{}.{} Parameters: [{}]", clazzName, methodName, requestBody); } } private void printResponseLog(HttpServletRequest request, String className, String methodName, Object returnObj, long usage) throws JsonProcessingException { if (log.isDebugEnabled()) { String returningData = null; if (returnObj != null) { if (returnObj.getClass().isAssignableFrom(byte[].class)) { returningData = "Binary data"; } else { returningData = JsonUtils.objectToJson(returnObj); } } log.debug("{}.{} Response: [{}], usage: [{}]ms", className, methodName, returningData, usage); } } }
参考文献:
代码学习来源
最后
以上就是心灵美黑米最近收集整理的关于Spring Aspect编程中@Around注解的使用及接口Controller监控的全部内容,更多相关Spring内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复