一、定义注解
package com.dstcar.common.annotations;
import java.lang.annotation.*;
/**
* @ClassName: ServiceAdjustRecord
* @Description: 服务组织监控记录注解
* @Author: liu wei ping
* @Date: 2023/3/15 10:36
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ServeOrgMonitor {
/**
* value值
* @return
*/
String cityId() default "";
/**
* serveCityCode值
* @return
*/
String serveCityCode() default "";
}
二、定义切面类
package com.dst.common.aspect;
import com.dstcar.common.annotations.ServeOrgMonitor;
import com.dstcar.common.utils.json.JsonUtil;
import com.dstcar.common.utils.string.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
/**
* @ClassName: ServerAspect
* @Description:
* @Author: liu wei ping
* @Date: 2023/3/15 10:36
*/
@Slf4j
@Aspect
@Component
public class ServerAspect {
private ExpressionParser parser = new SpelExpressionParser();
private LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
@Pointcut("@annotation(serveOrgMonitor)")
public void pointcut(ServeOrgMonitor serveOrgMonitor) {
}
/**
* 前置切入
* @param joinPoint
*/
@Before("pointcut(serveOrgMonitor)")
public void doBefore(JoinPoint joinPoint, ServeOrgMonitor serveOrgMonitor) {
try {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//方法注解信息
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());//文件带上当前时间
Object[] args = joinPoint.getArgs();
//获取方法的参数值
EvaluationContext context = this.bindParam(method, args);
//根据spel表达式获取值
Expression cityIdExpression = parser.parseExpression(serveOrgMonitor.cityId());
Expression serveCityCodeExpression = parser.parseExpression(serveOrgMonitor.serveCityCode());
Object cityId = cityIdExpression.getValue(context);
Object serveCityCode = serveCityCodeExpression.getValue(context);
if (Objects.nonNull(cityId) && StringUtil.isEmpty(serveCityCode)) {
log.info("组织架构调整监控报错:url:{},{},时间:{}", request.getRequestURI(), JsonUtil.toJson(args), dateStr);
}
} catch (Exception e) {
log.error(e.getMessage());
}
}
/**
* 将方法的参数名和参数值绑定
*
* @param method 方法,根据方法获取参数名
* @param args 方法的参数值
* @return
*/
private EvaluationContext bindParam(Method method, Object[] args) {
//获取方法的参数名
String[] params = discoverer.getParameterNames(method);
//将参数名与参数值对应起来
EvaluationContext context = new StandardEvaluationContext();
for (int len = 0; len < params.length; len++) {
context.setVariable(params[len], args[len]);
}
return context;
}
}
三、在调用方法上增加定义的注解
/**
* 预占明细分页查询
*
* @param query 查询条件
* @return 预占明细分页
*/
@ServeOrgMonitor(cityId = "#query.cityId",serveCityCode = "#query.serveCityCode")
public PageInfo<InventoryPreemptVO> getPreemptInventoryPage(InventoryPreemptQuery query) {
query.enablePage();
if (!StringUtil.isEmpty(query.getGoodsId()) && StringUtil.isEmpty(query.getGoodsCode())) {
GoodsManageOut goodsManage = goodsManageService.getGoodsById(query.getGoodsId());
if (Objects.isNull(goodsManage)) {
// 说明传的是无效商品,返回空
return new PageInfo<>();
}
query.setGoodsCode(goodsManage.getGoodsCode());
}
List<InventoryPreemptVO> result = inventoryPreemptMapper.getPreemptInventoryPage(query);
TranslationConvertUtil.convertList(result);
return PageInfo.of(result);
}
四、效果如图