spring aop log,springboot+aop切點記錄請求和響應信息

 2023-10-08 阅读 33 评论 0

摘要: 本篇主要分享的是springboot中結合aop方式來記錄請求參數和響應的數據信息;這里主要講解兩種切入點方式,一種方法切入,一種注解切入;首先創建個springboot測試工程并通過maven添加如下依賴: 復制代碼<!-- AOP --><dependency&g

 本篇主要分享的是springboot中結合aop方式來記錄請求參數和響應的數據信息;這里主要講解兩種切入點方式,一種方法切入,一種注解切入;首先創建個springboot測試工程并通過maven添加如下依賴:

復制代碼
<!-- AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

    <!--阿里 FastJson依賴--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.44</version></dependency>

復制代碼
  先來說方法的切點方式,需要創建個名為LogAspect的組件類,然后用@Aspect注解修飾組件類,再通過設置方法切入點方式做公共日志記錄,如下創建切入點:

spring aop log,復制代碼
//切點入口 Controller包下面所有類的所有方法
private final String pointcut = "execution( com.platform.Controller..(..))";

//切點
@Pointcut(value = pointcut)
public void log() {
}

復制代碼
  這里的execution( com.platform.Controller..(..))主要的意思是:切入點入口是Controller包下面所有類的所有方法;再來通過@Around環繞注解方法里面做請求參數和響應信息的記錄,如下代碼:

復制代碼
@Around(value = "log()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object result = null;
StringBuilder sbLog = new StringBuilder("\n");
try {
sbLog.append(String.format("類名:%s\r\n", proceedingJoinPoint.getTarget().getClass().getName()));

        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();sbLog.append(String.format("方法:%s\r\n", methodSignature.getMethod().getName()));Object[] args = proceedingJoinPoint.getArgs();for (Object o : args) {sbLog.append(String.format("參數:%s\r\n", JSON.toJSON(o)));}long startTime = System.currentTimeMillis();result = proceedingJoinPoint.proceed();long endTime = System.currentTimeMillis();sbLog.append(String.format("返回:%s\r\n", JSON.toJSON(result)));sbLog.append(String.format("耗時:%ss", endTime - startTime));} catch (Exception ex) {sbLog.append(String.format("異常:%s", ex.getMessage()));} finally {logger.info(sbLog.toString());}return result;
}

復制代碼
  此刻主要代碼就完成了,再來我們配置下日志的記錄方式;首先在 resources目錄增加名為logback-spring.xml的文件,其配置信息如:

java異步返回結果。復制代碼
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3 ~ Author:shenniu003
4 ~ Copyright (c) 2018.
5 -->
6
7 <configuration debug="false" scan="true" scanPeriod="1 seconds">
8
9 <springProperty scope="context" name="appname" source="logging.logback.appname"/>
10 <springProperty scope="context" name="logLevel" source="logging.logback.level"/>
11 <springProperty scope="context" name="logPath" source="logging.logback.path"/>
12
13 <property name="logPathAll" value="${logPath}/${appname}.log"/>
14
15 <contextName>logback</contextName>
16
17 <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
18 <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter" >
19 <level>WARN</level>
20 </filter>-->
21 <encoder>
22 <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
23 </encoder>
24 </appender>
25
26 <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
27 <file>${logPathAll}</file>
28 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
29 <fileNamePattern>${logPathAll}.%d{yyyy-MM-dd}.zip</fileNamePattern>
30 </rollingPolicy>
31 <encoder>
32 <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
33 </pattern>
34 </encoder>
35 </appender>
36
37 <root level="${logLevel}">
38 <appender-ref ref="console"/>
39 <appender-ref ref="file"/>
40 </root>
41
42 </configuration>
復制代碼
  然后application.yml的配置信息如:

復制代碼
1 logging:
2 config: classpath:logback-spring.xml
3 logback:
4 level: info #info ,debug
5 path: /home/app/data/applogs/weblog
6 appname: web
復制代碼
  此刻日志和公共的aop記錄類都完成了,我們需要創建個測試用例,其代碼如:

復制代碼
1 @PostMapping("/addUser")
2 public ResponseEntity<MoStudent> addUser(@RequestBody MoStudent moStudent) throws Exception {
3 moStudent.setNumber(UUID.randomUUID().toString());
4 // throw new Exception("錯誤了");
5 return new ResponseEntity<>(moStudent, HttpStatus.OK);
6 }
復制代碼
  最后,通過postman模擬post請求,能夠得到如下的日志結果:

  

Springboot注解。  上面的方式切入點是所有方法,所有方法都記錄日志可能有是不是需求想要的,此時可以通過注解的方式來標記想記錄日志的方法;先來創建個日志注解:

復制代碼
1 @Target(ElementType.METHOD)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 public @interface LogAnnotation {
5 /*
6
描述
7
8
@return
9 */
10 String des() default "";
11 }
復制代碼
  同樣再來創建注解的切入點:

復制代碼
1 //匹配方法上包含此注解的方法
2 private final String annotationPointCut = "@annotation(com.platform.Aop.LogAnnotation)";
3
4 //注解切點
5 @Pointcut(value = annotationPointCut)
6 public void logAnnotation() {
7 }
復制代碼
  再通過@Around注解綁定具體的操作方法:

復制代碼
1 @Around(value = "logAnnotation()")
2 public Object aroundAnnotation(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
3 Object result = null;
4 StringBuilder sbLog = new StringBuilder("\n");
5 try {
6 sbLog.append(String.format("類名:%s\r\n", proceedingJoinPoint.getTarget().getClass().getName()));
7
8 MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
9 Method method = methodSignature.getMethod();
10 LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
11 if (logAnnotation != null && !logAnnotation.des().isEmpty()) {
12 sbLog.append(String.format("說明:%s\r\n", logAnnotation.des()));
13 }
14 sbLog.append(String.format("方法:%s\r\n", method.getName()));
15
16 Object[] args = proceedingJoinPoint.getArgs();
17 for (Object o : args) {
18 sbLog.append(String.format("參數:%s\r\n", JSON.toJSON(o)));
19 }
20
21 long startTime = System.currentTimeMillis();
22 result = proceedingJoinPoint.proceed();
23 long endTime = System.currentTimeMillis();
24 sbLog.append(String.format("返回:%s\r\n", JSON.toJSON(result)));
25 sbLog.append(String.format("耗時:%ss", endTime - startTime));
26 } catch (Exception ex) {
27 sbLog.append(String.format("異常:%s", ex.getMessage()));
28 } finally {
29 logger.info(sbLog.toString());
30 }
31 return result;
32 }
復制代碼
  這個方法里需要注意的是注解方式相比第一種其實就多了如下幾行代碼:

上一個接口的返回值下一個接口用到?1 Method method = methodSignature.getMethod();
2 LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
3 if (logAnnotation != null && !logAnnotation.des().isEmpty()) {
4 sbLog.append(String.format("說明:%s\r\n", logAnnotation.des()));
5 }
  下面是注解測試用例:

復制代碼
1 @LogAnnotation(des = "注解記錄日志")
2 @PostMapping("/addUser01")
3 public ResponseEntity<MoStudent> addUser01(@RequestBody MoStudent moStudent) throws Exception {
4 moStudent.setNumber(UUID.randomUUID().toString());
5 return new ResponseEntity<>(moStudent, HttpStatus.OK); 歡迎工作一到五年的Java工程師朋友們加入Java群: 891219277
群內提供免費的Java架構學習資料(里面有高可用、高并發、高性能及分布式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!

6 }
復制代碼

轉載于:https://blog.51cto.com/14084556/2335046

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/130248.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息