前言
结合公司最近的需求,需要对一些配置进行日志跟踪,经过思考后发现这个场景非常适合AOP的应用,于是有了这一篇实战记录,话不多说直接开干。
定义注解
package com.linksame.iot.apijson.configuration.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Author Ivan
* @Date 2023/11/30 16:06
* @Description
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Record {
/**
* 配置标识
*/
String config() default "";
/**
* 操作标识
*/
String operation() default "";
}
注解实现
package com.linksame.iot.apijson.configuration.aspect;
import com.alibaba.fastjson.JSON;
import com.linksame.iot.apijson.configuration.annotation.Record;
import com.linksame.iot.apijson.configuration.params.ServerParams;
import com.linksame.iot.apijson.configuration.service.RecordService;
import com.linksame.iot.common.core.util.R;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.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.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @Author Ivan
* @Date 2023/11/30 16:03
* @Description
*/
@Slf4j
@Aspect
@Component
@AllArgsConstructor
public class RecordAspect {
private final RecordService recordService;
//@Record标识为切入点,切面会根据@Record注解来注入数据
@Pointcut("@annotation(com.linksame.iot.apijson.configuration.annotation.Record)")
public void logPointCut(){}
//环绕注入
@Around("logPointCut()")
public R around(ProceedingJoinPoint point) throws Throwable {
Object result = point.proceed();//执行目标方法
//日志信息记录
MethodSignature methodSignature = (MethodSignature) point.getSignature();
Method method = methodSignature.getMethod();
Record record = method.getDeclaredAnnotation(Record.class);
// String className = point.getTarget().getClass().getName();//类名
// String methodName = method.getName();//方法名
//入参信息
Object[] args = point.getArgs();
ServerParams params = JSON.parseObject(JSON.toJSONString(args[0]), ServerParams.class);
log.info("入参信息: {}", params);
log.info("配置标识: {}", record.config());
log.info("操作标识: {}", record.operation());
log.info("执行结果: {}", result);
R r = JSON.parseObject(JSON.toJSONString(result), R.class);
if(r.getCode() == 0){
//权限基础配置
com.linksame.iot.apijson.configuration.entity.Record recordData = new com.linksame.iot.apijson.configuration.entity.Record();
String serverName = "system", serverReadme = "系统后台", createBy = "超级管理员";
recordData.setConfigFlag(record.config());
recordData.setOperationFlag(record.operation());
if(StringUtils.isNotBlank(params.getServerName())){
serverName = params.getServerName();
}
if(StringUtils.isNotBlank(params.getServerName())){
serverReadme = params.getServerReadme();
}
if(StringUtils.isNotBlank(params.getCreateBy())){
createBy = params.getCreateBy();
}
recordData.setServerName(serverName);
recordData.setServerReadme(serverReadme);
recordData.setCreateBy(createBy);
//method
if(record.config().equalsIgnoreCase("Access")){
recordData.setMethodFlag("查询");
}
if(record.config().equalsIgnoreCase("Request")){
if(params.getMethod().equalsIgnoreCase("POST")){
recordData.setMethodFlag("新增");
}
if(params.getMethod().equalsIgnoreCase("PUT")){
recordData.setMethodFlag("修改");
}
if(params.getMethod().equalsIgnoreCase("DELETE")){
recordData.setMethodFlag("删除");
}
}
//configId
if(record.operation().equals("注册")){
recordData.setConfigId(r.getData().toString());
}
if(record.operation().equals("更新") || record.operation().equals("删除")){
recordData.setConfigId(params.getId());
}
recordService.save(recordData);
}
return r;
}
}
注解应用
/**
* 创建
* @param accessParams
* @return
*/
@Record(config = "Access", operation = "注册")
@PostMapping
public R save(@RequestBody AccessParams accessParams){
return accessService.saveAccess(accessParams);
}