使用SpringBoot+AOP實(shí)現(xiàn)可插拔式日志的示例代碼
一、AOP
AOP為Aspect Oriented Programming的縮寫(xiě),意為:面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。 AOP是OOP的延續(xù),是軟件開(kāi)發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。
二、實(shí)現(xiàn)
引入依賴(lài)
<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類(lèi)
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類(lèi)
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類(lèi)
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, 然后訪(fǎng)問(wèn)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í)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringCloud融入Python的實(shí)現(xiàn)
這篇文章主要介紹了SpringCloud融入Python的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
攔截JSP頁(yè)面,校驗(yàn)是否已登錄詳解及實(shí)現(xiàn)代碼
這篇文章主要介紹了攔截JSP頁(yè)面,校驗(yàn)是否已登錄詳解及實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-11-11
理解java多線(xiàn)程中ExecutorService使用
這篇文章主要幫助大家理解java多線(xiàn)程中ExcetorServiced的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
IntelliJ IDEA使用SVN分支的簡(jiǎn)單介紹
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA使用SVN分支的簡(jiǎn)單介紹,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
Java基于享元模式實(shí)現(xiàn)五子棋游戲功能實(shí)例詳解
這篇文章主要介紹了Java基于享元模式實(shí)現(xiàn)五子棋游戲功能,較為詳細(xì)的分析了享元模式的概念、功能并結(jié)合實(shí)例形式詳細(xì)分析了Java使用享元模式實(shí)現(xiàn)五子棋游戲的具體操作步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下2018-05-05
Spring boot項(xiàng)目使用thymeleaf模板過(guò)程詳解
這篇文章主要介紹了Spring boot項(xiàng)目使用thymeleaf模板過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Java操作數(shù)據(jù)庫(kù)(行級(jí)鎖,for update)
這篇文章主要介紹了Java操作數(shù)據(jù)庫(kù)(行級(jí)鎖,for update),文章圍繞Java操作數(shù)據(jù)庫(kù)的相關(guān)資料展開(kāi)詳細(xì)內(nèi)容,需要的小伙伴可以參考一下,希望對(duì)你有所幫助2021-12-12

