添加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调用返回成功
就这样吧!