使用SpringBoot+AOP實(shí)現(xiàn)可插拔式日志的示例代碼
一、AOP
AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。 AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。
二、實(shí)現(xiàn)
引入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
新建SysLog類
package com.example.aop.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SysLog { String value() default " "; }
新建SysLogAspect類
package com.example.aop.annotation; import com.example.aop.service.LogService; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.lang.reflect.Method; @Aspect @Component public class SysLogAspect { @Autowired private LogService logService; @Pointcut("@annotation(com.example.aop.annotation.SysLog)") public void logPointCut() {} @Before("logPointCut()") public void before(JoinPoint joinPoint) { long beginTime = System.currentTimeMillis(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SysLog annotation = method.getAnnotation(SysLog.class); String value = annotation.value(); Object[] args = joinPoint.getArgs(); try { logService.log(beginTime, "before " + method.getName()); } catch (Exception e) { } } @Around("logPointCut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { long beginTime = System.currentTimeMillis(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SysLog annotation = method.getAnnotation(SysLog.class); String value = annotation.value(); Object[] args = joinPoint.getArgs(); Object object = joinPoint.proceed(args); try { logService.log(beginTime, "around " + method.getName()); } catch (Exception e) { } return object; } @After("logPointCut()") public void after(JoinPoint joinPoint) { long beginTime = System.currentTimeMillis(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SysLog annotation = method.getAnnotation(SysLog.class); String value = annotation.value(); Object[] args = joinPoint.getArgs(); try { logService.log(beginTime, "after " + method.getName()); } catch (Exception e) { } } @AfterReturning("logPointCut()") public void afterReturning(JoinPoint joinPoint) { long beginTime = System.currentTimeMillis(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SysLog annotation = method.getAnnotation(SysLog.class); String value = annotation.value(); Object[] args = joinPoint.getArgs(); try { logService.log(beginTime, "after returning " + method.getName()); } catch (Exception e) { } } @AfterThrowing("logPointCut()") public void afterThrowing(JoinPoint joinPoint) { long beginTime = System.currentTimeMillis(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SysLog annotation = method.getAnnotation(SysLog.class); String value = annotation.value(); Object[] args = joinPoint.getArgs(); try { logService.log(beginTime, "after throwing " + method.getName()); } catch (Exception e) { } } }
新建TestService類
package com.example.aop.service; import com.example.aop.dto.TestDomain; import com.example.aop.annotation.SysLog; import org.springframework.stereotype.Service; @Service public class TestService { @SysLog("log-1") public void log1(String name, TestDomain testDomain) { System.out.println("print log 1" + name + " " + testDomain.toString()); } @SysLog("log-2") public void log2(String name, TestDomain testDomain) { System.out.println("print log 2" + name + " " + testDomain.toString()); } @SysLog("throw-exception") public void throwException() { System.out.println("throw exception"); int i = 3/0; } }
新建TestController
package com.example.aop.controller; import com.example.aop.dto.TestDomain; import com.example.aop.service.TestService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @Autowired private TestService testService; @GetMapping("test") public String test(@RequestParam("p1") String p1) { TestDomain testDomain = new TestDomain(); testDomain.setId("1"); testDomain.setTitle("t1"); testService.log1(p1, testDomain); testService.log2(p1, testDomain); testService.throwException(); return "hello aop"; } }
三、測(cè)試
運(yùn)行AopApplication, 然后訪問http://localhost:8080/test?p1=123,可以看到控制臺(tái)有以下輸出:
before log1 at: 1554903984403
print log 1123 com.example.aop.dto.TestDomain@2a7a4cd5
around log1 at: 1554903984402
after log1 at: 1554903984409
after returning log1 at: 1554903984409
before log2 at: 1554903984409
print log 2123 com.example.aop.dto.TestDomain@2a7a4cd5
around log2 at: 1554903984409
after log2 at: 1554903984410
after returning log2 at: 1554903984410
before throwException at: 1554903984410
throw exception
after throwException at: 1554903984410
after throwing throwException at: 1554903984410
github地址:https://github.com/lijun003/SpringBoot-AOP-log
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- SpringBoot中使用AOP打印接口日志的方法
- 詳解基于SpringBoot使用AOP技術(shù)實(shí)現(xiàn)操作日志管理
- springboot配置aop切面日志打印過程解析
- Springboot使用@Valid 和AOP做參數(shù)校驗(yàn)及日志輸出問題
- Springboot接口項(xiàng)目如何使用AOP記錄日志
- SpringBoot AOP處理請(qǐng)求日志打印功能代碼實(shí)例
- 在springboot中使用AOP進(jìn)行全局日志記錄
- Springboot2 配置AOP日志的方法步驟
- 解析springboot集成AOP實(shí)現(xiàn)日志輸出的方法
- springboot使用自定義注解實(shí)現(xiàn)aop切面日志
相關(guān)文章
一文帶你掌握J(rèn)ava?SPI的原理和實(shí)踐
在Java中,我們經(jīng)常會(huì)提到面向接口編程,這樣減少了模塊之間的耦合,更加靈活,Java?SPI?(Service?Provider?Interface)就提供了這樣的機(jī)制,本文就來講講它的原理與具體使用吧2023-05-05java開發(fā)Activiti進(jìn)階篇流程實(shí)例詳解
這篇文章主要為大家介紹了java開發(fā)Activiti進(jìn)階篇流程實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08java中優(yōu)化大量if...else...方法總結(jié)
在我們平時(shí)的開發(fā)過程中,經(jīng)??赡軙?huì)出現(xiàn)大量If else的場(chǎng)景,代碼顯的很臃腫,非常不優(yōu)雅,下面這篇文章主要給大家介紹了關(guān)于java中優(yōu)化大量if...else...方法的相關(guān)資料,需要的朋友可以參考下2023-03-03java基于C/S模式實(shí)現(xiàn)聊天程序(服務(wù)器)
這篇文章主要為大家詳細(xì)介紹了java基于C/S模式實(shí)現(xiàn)聊天程序的服務(wù)器篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01java虛擬機(jī)學(xué)習(xí)筆記基礎(chǔ)篇
在本篇文章里小編給大家整理的是關(guān)于java虛擬機(jī)學(xué)習(xí)筆記的相關(guān)內(nèi)容,分享了一些基礎(chǔ)知識(shí)點(diǎn),需要的朋友們參考下。2019-06-06