目的是在controller層加上入參和返回參數的日誌,可以打印info日誌,也可以將操作記錄存庫。實現方式是在controller層做切面,然後動態代理加上log。
環境:springboot,gradle
- 引入aop的包
compile ("org.springframework.boot:spring-boot-starter-aop:${springBootVersion}")
- 編寫切面類
/**
* 系統日誌,切面處理類
*
*
*/
@Aspect //切面註解
@Component //註冊爲bean,目的是讓spring掃描到
public class ControllerAspect {
/**
* 添加切面的類,我這裏將項目的controller類均添加切面
*
* !execution後面匹配的是排除的類,如果有不需要做日誌的類,放在這裏
* 兩個條件用 &&相連
*/
@Pointcut("execution(* com.aaaa.*.controller..*.*(..)) && !execution(* com.***.bbb.controller..*.*(..))")
public void logPointCut() {
}
/**
*做環繞處理,即方法進入和退出都在這個方法裏
*/
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
//執行方法
Object result = point.proceed();
//執行時長(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日誌
saveSysLog(point, time);
return result;//因爲切面環繞是給controller類添加了一個動態代理,這裏需要將返回值返回,否則接口就沒有返回值了。
}
private void saveSysLog(ProceedingJoinPoint joinPoint, long time) throws Exception {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
ApiOperation operation = method.getAnnotation(ApiOperation.class);//ApiOperation是swagger的註解,若項目使用了swagger,可以獲取接口描述
SysLogEntity sysLog = new SysLogEntity();//這是記錄日誌的實體類,可根據具體情況自己設置
if(operation != null){
//註解上的描述
sysLog.setOperation(operation.value());
}
//請求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMethod(className + "." + methodName);
//請求的參數
Object[] args = joinPoint.getArgs();
//獲取request
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
//設置IP地址 通過request獲取ip地址,工具類網上就有
sysLog.setIp(IPUtils.getIpAddr(request));
sysLog.setTime(time);
sysLog.setCreateDate(new Date());
}
}