spring boot自定義注解打印日志
在實際項目中可能需要監控每個接口的請求時間以及請求參數等相關信息,那么此時我們想到的就是兩種實現方式,一種是通過攔截器實現,另一種則通過AOP自定義注解實現。
本文介紹自定義注解實現方式
自定義注解,四個元注解這次就不解釋了。
1
2
3
4
5
6
7
8
|
@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface WebLog { /** * 日志信息描述 */ String description() default "" ; } |
AOP實現:
1.@Order注解用來定義切面的執行順序,數值越小優先級越高。
2.@Around環繞通知,我們可以自定義在什么時候執行@Before以及@After。
3.ThreadLocal針對每個線程都單獨的記錄。
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
|
@Aspect @Component public class WebLogAspect { private static ThreadLocal<ProceedingJoinPoint> td = new ThreadLocal<>(); @Pointcut ( "@annotation(com.example.demo.annotation.WebLog)" ) @Order ( 1 ) public void webLog(){} @Before ( "webLog()" ) public void doBefor(JoinPoint point){ System.out.println( "***********method before執行************" ); ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); System.out.println( "請求URL:" +request.getRequestURL()); System.out.println( "請求參數:" + Arrays.toString(point.getArgs())); System.out.println( "***********method before結束************" ); } @Around ( "webLog()" ) public Object doAround(ProceedingJoinPoint point) throws Throwable { System.out.println( "***********執行環繞方法開始************" ); td.set(point); long startTime = System.currentTimeMillis(); ProceedingJoinPoint joinPoint = td.get(); Object proceed = joinPoint.proceed(); System.out.println( "執行耗時毫秒:" + (System.currentTimeMillis()-startTime)); System.out.println( "***********執行環繞方法結束************" ); return proceed; } } |
Controller
1
2
3
4
5
6
7
8
|
@RestController public class LoginController { @PostMapping ( "/user/login" ) @WebLog (description = "用戶登錄接口" ) public UserForm login( @RequestBody UserForm user){ return user; } } |
測試結果
通過自定義注解獲取日志
1.定義一個注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package com.hisense.demo02; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author : sunkepeng E-mail : sunkepengouc@163.com * @date : 2020/8/8 20:09 */ @Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface Check { } |
2.寫一個測試用類,并使用注解
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
|
package com.hisense.demo02; /** * @author : sunkepeng E-mail : sunkepengouc@163.com * @date : 2020/8/8 20:04 */ public class Calculator { @Check public void add(){ System.out.println( "1+0=" + ( 1 + 0 )); } @Check public void sub(){ System.out.println( "1-0=" + ( 1 - 0 )); } @Check public void mul(){ System.out.println( "1*0=" + ( 1 * 0 )); } @Check public void div(){ System.out.println( "1/0=" + ( 1 / 0 )); } public void show(){ System.out.println( "永無bug" ); } } |
3.使用注解,在測試類中輸出log
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
|
package com.hisense.demo02; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Method; /** * @author : sunkepeng E-mail : sunkepengouc@163.com * @date : 2020/8/8 21:39 */ public class TestCheck { public static void main(String[] args) throws IOException { Calculator calculator = new Calculator(); Class calculatorClass = calculator.getClass(); Method[] methods = calculatorClass.getMethods(); int number = 0 ; BufferedWriter bufferedWriter = new BufferedWriter( new FileWriter( "bug.txt" )); for (Method method : methods) { if (method.isAnnotationPresent(Check. class )){ try { method.invoke(calculator); } catch (Exception e) { number++; bufferedWriter.write(method.getName()+ "出現異常" ); bufferedWriter.newLine(); bufferedWriter.write( "異常的名稱:" +e.getCause().getClass().getSimpleName()); bufferedWriter.newLine(); bufferedWriter.write( "異常的原因" +e.getCause().getMessage()); bufferedWriter.newLine(); bufferedWriter.write( "-----------------" ); bufferedWriter.newLine(); } } } bufferedWriter.write( "本次共出現:" +number+ "次異常" ); bufferedWriter.flush(); bufferedWriter.close(); } } |
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/kin_wen/article/details/93412270