SpringBoot開發教程之AOP日志處理
日志處理:
需求分析
日志處理需要記錄的是:
- 請求的URL
- 訪問者IP
- 調用的方法
- 傳入的參數
- 返回的內容
上面的內容要求在控制臺和日志中輸出。
在學習這部分知識的時候,真的感覺收獲很多,在之前Spring學習的aop隻是初步瞭解,現在有瞭一些深入的理解。好記性不如爛筆頭!
在日志處理這部分主要是aop的使用,通過切面的方式來整合到項目瞭,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高瞭開發的效率。
人話:Aop 在不改變原有代碼的情況下 , 去增加新的功能
需要瞭解的:
- 橫切關註點:跨越應用程序多個模塊的方法或功能。即是,與我們業務邏輯無關的,但是我們需要關註的部分,就是橫切關註點。如日志 , 安全 , 緩存 , 事務等等 ….
- 切面(ASPECT):橫切關註點 被模塊化 的特殊對象。即,它是一個類。
- 通知(Advice):切面必須要完成的工作。即,它是類中的一個方法。
- 切入點(PointCut):切面通知 執行的 “地點”的定義。
- 連接點(JointPoint):與切入點匹配的執行點。
通知(Advice)裡面還有幾種方法來幫助實現,這裡我列舉瞭該部分實現的方法:
- doBefore方法(方法前執行),需要註解@Before實現
- After方法(方法後執行),需要註解@After實現
- doAfterReturning方法,需要註解@AfterReturning實現
具體實現看後面部分。
重要部分:導入依賴
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <scope>test</scope> </dependency>
提醒:導入包以後,刷新下Maven,如果運行的時候找不到包,重啟試試,網上有很多的解決方法(也試過),最後個人隻是重啟一下子再刷新下maven就可以使用瞭。
這裡就沒有給出解決方法,隻是一個提醒。
實現過程:
創建一個類(LogAspect),將該類定義成一個切面(@Aspect)並且加入容器中(@Component)。
首先創建一個切入點,後面的Advice是建立在切入點上:
@Pointcut("execution(* com.blog.Controller..*.*(..))") public void log(){}
整個表達式可以分為五個部分
1、execution():表達式主體。
2、第一個*號:表示返回類型,*號表示所有的類型。
3、包名:表示需要攔截的包名,後面的兩個句點分別表示當前包和當前包的所有子包,com.blog.Controller包、子孫包下所有類的方法。
4、第二個*號:表示類名,*號表示所有的類。
5、*(..) :第三個星號表示方法名,*號表示所有的方法,後面括弧裡面表示方法的參數,兩個句點表示任何參數
定義完切入點後,處理前置通知和後置通知:
@Before("log()") public void doBefore(JoinPoint joinPoint){ System.out.println("在進入controller之前處理流-------------"); } @After("log()") public void doAfter(){ System.out.println("在進入controller之後處理流-------------"); } //在切入點return內容之後切入內容(可以用來對處理返回值做一些加工處理) @AfterReturning(returning = "result",pointcut="log()") public void doAfterReturning(Object result){ logger.info("Return ------ {}",result ); }
通過上述的簡單介紹,可以知道我們如果需要知道需求裡面的要求,我們的重點應該放到前置通知裡面,在流處理之前獲取前端操作的信息。
核心代碼如下:
//通過上下文來獲取請求裡面的信息 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //獲取封裝瞭署名信息的對象,在該對象中可以獲取到目標方法名,所屬類的Class等信息(反射) String classMethod = joinPoint.getSignature().getDeclaringTypeName()+","+joinPoint.getSignature().getName(); // 1. 獲取URL String url = request.getRequestURL().toString(); //2. 獲取ip地址 String addr = request.getRemoteAddr(); /*創建一個類RequestData,來保存相關信息*/ RequestData requestData = new RequestData( url, addr, classMethod, joinPoint.getArgs() ); //在控制臺打印出來 logger.info("RequestData------{}",requestData);
創建的類是內部類(RequestData),隻是封裝一下需要打印的信息。
實驗效果:
在進入controller之前處理流————-
2021-08-15 15:19:43.923 INFO 9644 — [nio-8080-exec-1] com.blog.AspectAop.LogAspect : RequestData——RequestData{url=’http://localhost:8080/’, ipAddr=’0:0:0:0:0:0:0:1′, classMethod=’com.blog.Controller.IndexController,index’, args=[]}
2021-08-15 15:19:43.932 INFO 9644 — [nio-8080-exec-1] com.blog.AspectAop.LogAspect : Return —— index
在進入controller之後處理流————-
項目的github地址
參考文獻:
狂神說Spring
表達式參數
總結
到此這篇關於SpringBoot開發教程之AOP日志處理的文章就介紹到這瞭,更多相關SpringBoot AOP日志處理 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- springboot日志切面通用類實例詳解
- Spring針對AOP詳細講解
- 解決spring項目找不到Aspect依賴註解的問題
- SpringBoot使用AOP記錄接口操作日志詳解
- SpringBoot整合Web之AOP配置詳解