1. 定义切面
代码语言:javascript复制@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
2.切面类
代码语言:javascript复制package aspect;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Objects;
@Aspect
@Component
public class LogAspect {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Pointcut("@annotation(Log)") //定义切面的类路径
public void pointcut() {
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable{
long beginTime = System.currentTimeMillis();
//增加返回值
Object proceed = null;
try {
// 执行方法
proceed = point.proceed();
} catch (Throwable e) {
logger.error("切面异常:",e);
throw e;
}
// 执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
// 保存日志
saveLog(point, time,proceed);
//关键,同时该参数作为入参存储在数据库中。
return proceed;
}
private void saveLog(ProceedingJoinPoint joinPoint, long time, Object proceed) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
//TODO存入日志表中
Log logAnnotation = method.getAnnotation(Log.class);
if (logAnnotation != null) {
// 注解上的描述
//Operation = (logAnnotation.value()); //TODO 操作名称
}
// 请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
//简称类名
String classNameSimple = joinPoint.getTarget().getClass().getSimpleName();
//Method = (classNameSimple "." methodName "()"); //TODO 执行类和方法
// 请求的方法参数值
Object[] args = joinPoint.getArgs();
// 请求的方法参数名称
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
String[] paramNames = u.getParameterNames(method);
if (args != null && paramNames != null) {
String params = "";
for (int i = 0; i < args.length; i ) {
logger.info(i " paramNames[i]=" paramNames[i] ",args[i]=" GsonUtils.toJson(args[i]));
params = " " paramNames[i] ": " GsonUtils.toJson(args[i]);
}
//Params = (params); //TODO 方法参数
}
//获取关键参数,比如外部订单号
Object argument = args[0];
//从参数中获取out_order_no
String jsonString = JSON.toJSONString(args[0]);
String outOrderNo = StringUtils.EMPTY;
if (argument instanceof String) {
outOrderNo = argument.toString();
jsonString = JSON.toJSONString(args);
} else if (isJSONObj(jsonString)) {
JSONObject jsonObject = JSON.parseObject(jsonString);
if (jsonObject.containsKey("out_order_no")) {
outOrderNo = jsonObject.getString("out_order_no");
}
} else if (isJSONArr(jsonString)) {
JSONArray jsonArray = JSON.parseArray(jsonString);
if (CollectionUtils.isNotEmpty(jsonArray) && Objects.nonNull(jsonArray.getJSONObject(0))) {
JSONObject jsonObject = jsonArray.getJSONObject(0);
if (jsonObject.containsKey("out_order_no")) {
outOrderNo = jsonObject.getString("out_order_no");
}
}
}
//OutOrderNo = (outOrderNo); //TODO 关键索引参数
//ReqTime = ((int) time); //TODO 请求时长
//查询返回值
logger.info("target=" joinPoint.getTarget());
logger.info("kind=" joinPoint.getKind());
logger.info("proceed=" proceed.toString()); //返回结果
//Resp = (GsonUtils.toJson(proceed)); //TODO 接口返回结果
// 保存系统日志
//saveSysLog(); //TODO save to database
}
public static boolean isJSONObj(String jsonStr){
if(StringUtils.isNotBlank(jsonStr) && jsonStr.startsWith("{") && jsonStr.endsWith("}")){
return true;
}
return false;
}
public static boolean isJSONArr(String jsonStr){
if(StringUtils.isNotBlank(jsonStr) && jsonStr.startsWith("[") && jsonStr.endsWith("]")){
return true;
}
return false;
}
}
3.测试类
代码语言:javascript复制@Log(value = "测试日志切面接口")
@GetMapping("/hello")
public String hello(@RequestParam("out_order_no") String name){
logger.info("request param is [{name}]",name);
LogEntity entity = new LogEntity();
entity.setOut_order_no("TB123456789");
String resp = log(entity);
logger.info("request resp is [{resp}]",resp);
return "hello" name ",resp=" resp;
}
@Log("测试日志切面方法")
@Override
public String log(LogEntity entity) {
return "success-log:" GsonUtils.toJson(entity);
}
public class LogEntity {
private String out_order_no;
public String getOut_order_no() {
return out_order_no;
}
public void setOut_order_no(String out_order_no) {
this.out_order_no = out_order_no;
}
}