添加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>
日誌實體類
package com.baidu.entity;
import lombok.Data;
@Data
public class RequestLog {
/**
* 主鍵
*/
private int id;
/**
* 操作方式
*
* 1:查詢
*/
private Integer operateType;
/**
* 查詢內容
*/
private String operateContent;
/**
* 請求內容
*/
private String request;
/**
* 訪問IP
*/
private String ip;
/**
* 請求結果
*
* 1:成功 -1:失敗
*/
private String resultCode;
/**
* 錯誤信息
*/
private String errorMessage;
/**
* 操作時間
*/
private Long time;
/**
* 備註,預留字段
*/
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;
/**
* 操作內容
*/
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表達式這裏寫註解的全路徑,
* 若想在某個包下面切入,就寫那個包路徑,例如,com.baidu.controller,這樣會切入整個controller包下面的類
* Poincut表達式不多說,大家可以去百度一下
*/
@Pointcut("@annotation(com.baidu.annotation.LogOperation)" )
public void pointcut(){}
@Around("pointcut()")
public Object process(ProceedingJoinPoint point) throws Throwable {
Object returnValue = point.proceed();
return returnValue;
}
/**
* 返回增強,目標方法正常執行完畢時執行
* @param point
* @param returnValue
*/
@AfterReturning(pointcut="pointcut()", returning="returnValue")
public void afterReturningMethod(JoinPoint point, Object returnValue) {
log.info("@AfterReturning:查詢成功");
addRequestLog(point, returnValue);
}
/**
* 異常拋出增強,目標方法發生異常的時候執行
* @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();//這是請求參數,是個數組
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()));//這是請求參數,是個數組
requestLog.setResultCode(result.getResultCode());
requestLog.setTime(new Date().getTime());
log.info("插入日誌requestLog={}", requestLog.toString());
//插入數據庫 懶得寫了
}
private <T> T transform(Object obj, Class<T> clazz) {
return JSON.parseObject(JSON.toJSONString(obj), clazz);
}
}
測試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","成功","", "成功啦");
}
}
返回實體類
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;
}
/**
* 錯誤碼
*/
private String resultCode;
/**
* 提示信息
*/
private String message;
/**
* 錯誤信息
*/
private String errorMessage;
/**
* 返回數據
*/
private Object result;
}
用戶實體類
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調用返回成功
就這樣吧!