使用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í)有所幫助,也希望大家多多支持腳本之家。
- SpringBoot中使用AOP打印接口日志的方法
- 詳解基于SpringBoot使用AOP技術(shù)實(shí)現(xiàn)操作日志管理
- springboot配置aop切面日志打印過(guò)程解析
- Springboot使用@Valid 和AOP做參數(shù)校驗(yàn)及日志輸出問(wè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ī)制,本文就來(lái)講講它的原理與具體使用吧2023-05-05
基于java的opencv開(kāi)發(fā)過(guò)程詳解
這篇文章主要介紹了基于java的opencv開(kāi)發(fā)過(guò)程詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
java開(kāi)發(fā)Activiti進(jìn)階篇流程實(shí)例詳解
這篇文章主要為大家介紹了java開(kāi)發(fā)Activiti進(jìn)階篇流程實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
java中優(yōu)化大量if...else...方法總結(jié)
在我們平時(shí)的開(kāi)發(fā)過(guò)程中,經(jīng)??赡軙?huì)出現(xiàn)大量If else的場(chǎng)景,代碼顯的很臃腫,非常不優(yōu)雅,下面這篇文章主要給大家介紹了關(guān)于java中優(yōu)化大量if...else...方法的相關(guān)資料,需要的朋友可以參考下2023-03-03
java基于C/S模式實(shí)現(xiàn)聊天程序(服務(wù)器)
這篇文章主要為大家詳細(xì)介紹了java基于C/S模式實(shí)現(xiàn)聊天程序的服務(wù)器篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
java虛擬機(jī)學(xué)習(xí)筆記基礎(chǔ)篇
在本篇文章里小編給大家整理的是關(guān)于java虛擬機(jī)學(xué)習(xí)筆記的相關(guān)內(nèi)容,分享了一些基礎(chǔ)知識(shí)點(diǎn),需要的朋友們參考下。2019-06-06
Java Spring boot 2.0 跨域問(wèn)題的解決
本篇文章主要介紹了Java Spring boot 2.0 跨域問(wèn)題的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04

