Springboot項(xiàng)目使用AOP與自定義注解記錄請(qǐng)求日志方式
添加Maven依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>日志實(shí)體類
package com.baidu.entity;
import lombok.Data;
@Data
public class RequestLog {
/**
* 主鍵
*/
private int id;
/**
* 操作方式
*
* 1:查詢
*/
private Integer operateType;
/**
* 查詢內(nèi)容
*/
private String operateContent;
/**
* 請(qǐng)求內(nèi)容
*/
private String request;
/**
* 訪問IP
*/
private String ip;
/**
* 請(qǐng)求結(jié)果
*
* 1:成功 -1:失敗
*/
private String resultCode;
/**
* 錯(cuò)誤信息
*/
private String errorMessage;
/**
* 操作時(shí)間
*/
private Long time;
/**
* 備注,預(yù)留字段
*/
private String remark;
}自定義注解
package com.baidu.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogOperation {
/**
* 操作類型
*/
public int operateType() default 1;
/**
* 操作內(nèi)容
*/
public String operateContent();
/**
* 備注
*/
public String remark();
}AOP切面類
package com.baidu.aspect;
import java.util.Arrays;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.baidu.annotation.LogOperation;
import com.baidu.entity.RequestLog;
import com.baidu.entity.Result;
import com.baidu.entity.UserEntity;
import lombok.extern.slf4j.Slf4j;
@Aspect
@Component
@Slf4j
public class RequestLogAspect {
@Autowired
private HttpServletRequest request;
/**
* 這邊由于我只需自定義注解,所以Poincut表達(dá)式這里寫注解的全路徑,
* 若想在某個(gè)包下面切入,就寫那個(gè)包路徑,例如,com.baidu.controller,這樣會(huì)切入整個(gè)controller包下面的類
* Poincut表達(dá)式不多說,大家可以去百度一下
*/
@Pointcut("@annotation(com.baidu.annotation.LogOperation)" )
public void pointcut(){}
@Around("pointcut()")
public Object process(ProceedingJoinPoint point) throws Throwable {
Object returnValue = point.proceed();
return returnValue;
}
/**
* 返回增強(qiáng),目標(biāo)方法正常執(zhí)行完畢時(shí)執(zhí)行
* @param point
* @param returnValue
*/
@AfterReturning(pointcut="pointcut()", returning="returnValue")
public void afterReturningMethod(JoinPoint point, Object returnValue) {
log.info("@AfterReturning:查詢成功");
addRequestLog(point, returnValue);
}
/**
* 異常拋出增強(qiáng),目標(biāo)方法發(fā)生異常的時(shí)候執(zhí)行
* @param point
* @param e
*/
@AfterThrowing(value = "pointcut()", throwing = "e")
public void afterThorwingMethod(JoinPoint point, Exception e) {
log.info("@AfterThrowing:查詢失敗");
addRequestLog(point, null);
}
//省略了@After、@Before
private void addRequestLog(JoinPoint point, Object returnValue) {
MethodSignature signature = (MethodSignature)point.getSignature();
LogOperation logOperation = signature.getMethod().getAnnotation(LogOperation.class);
if(logOperation == null) {
return;
}
Result result = transform(returnValue, Result.class);
if(result==null) {
result = new Result();
}
Object[] objs = point.getArgs();//這是請(qǐng)求參數(shù),是個(gè)數(shù)組
UserEntity user = transform(objs[0], UserEntity.class);
String id = String.valueOf(objs[1]);
log.info("id={},user={}", id, user.toString());
RequestLog requestLog = new RequestLog();
requestLog.setIp(request.getRemoteAddr());
requestLog.setOperateContent(logOperation.operateContent());
requestLog.setOperateType(logOperation.operateType());
requestLog.setRemark("");
requestLog.setRequest(Arrays.toString(point.getArgs()));//這是請(qǐng)求參數(shù),是個(gè)數(shù)組
requestLog.setResultCode(result.getResultCode());
requestLog.setTime(new Date().getTime());
log.info("插入日志requestLog={}", requestLog.toString());
//插入數(shù)據(jù)庫(kù) 懶得寫了
}
private <T> T transform(Object obj, Class<T> clazz) {
return JSON.parseObject(JSON.toJSONString(obj), clazz);
}
}測(cè)試Controller
package com.baidu.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baidu.annotation.LogOperation;
import com.baidu.entity.Result;
import com.baidu.entity.UserEntity;
@RestController
@RequestMapping("/user")
public class RequeatLogTest {
@LogOperation(operateType= 1, operateContent = "查找用戶列表", remark = "暫無備注")
@PostMapping("/select")
public Result selectUserList(UserEntity user, String id) {
return new Result("1","成功","", "成功啦");
}
}返回實(shí)體類
package com.baidu.entity;
import java.io.Serializable;
import lombok.Data;
@Data
public class Result implements Serializable{
/**
*
*/
private static final long serialVersionUID = 6103309328749274117L;
public Result() {
}
public Result(String resultCode, String message, String errorMessage, Object result) {
this.resultCode = resultCode;
this.message = message;
this.errorMessage = errorMessage;
this.result = result;
}
/**
* 錯(cuò)誤碼
*/
private String resultCode;
/**
* 提示信息
*/
private String message;
/**
* 錯(cuò)誤信息
*/
private String errorMessage;
/**
* 返回?cái)?shù)據(jù)
*/
private Object result;
}用戶實(shí)體類
package com.baidu.entity;
import java.io.Serializable;
import lombok.Data;
@Data
public class UserEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = 4477284653938772276L;
private String name;
private int age;
private String gender;
}用Postman調(diào)用返回成功


就這樣吧!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java將一個(gè)目錄下的所有數(shù)據(jù)復(fù)制到另一個(gè)目錄下
這篇文章主要為大家詳細(xì)介紹了java將一個(gè)目錄下的所有數(shù)據(jù)復(fù)制到另一個(gè)目錄下,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
java中分組統(tǒng)計(jì)的三種實(shí)現(xiàn)方式
這篇文章主要介紹了java中分組統(tǒng)計(jì)的三種實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
解決java.lang.ClassNotFoundException: com.mysql.cj.jdbc.D
這篇文章主要介紹了解決java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver報(bào)錯(cuò)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Java使用BigDecimal進(jìn)行運(yùn)算封裝的實(shí)際案例
今天小編就為大家分享一篇關(guān)于Java使用BigDecimal進(jìn)行運(yùn)算封裝的實(shí)際案例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
java開發(fā)之讀寫txt文件操作的實(shí)現(xiàn)
本篇文章介紹了,java開發(fā)之讀寫txt文件操作的實(shí)現(xiàn)。需要的朋友參考下2013-05-05
Spring事務(wù)中的事務(wù)傳播行為使用方式詳解
Spring框架作為一個(gè)輕量級(jí)的開源框架,在企業(yè)應(yīng)用開發(fā)中被廣泛使用,在Spring事務(wù)管理中,事務(wù)傳播行為是非常重要的一部分,它定義了方法如何參與到已經(jīng)存在的事務(wù)中或者如何開啟新的事務(wù),本文將詳細(xì)介紹Spring事務(wù)中的幾種事務(wù)傳播行為,詳細(xì)講解具體使用方法2023-06-06
Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type
這篇文章主要介紹了Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type的相關(guān)資料,需要的朋友可以參考下2017-05-05
詳解Springboot Oauth2 Server搭建Oauth2認(rèn)證服務(wù)
這篇文章主要介紹了Springboot Oauth2 Server 搭建Oauth2認(rèn)證服務(wù),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05

