面向切面编程
1.具体场景
例: 打印接口详细入参日志
2.自定义注解
自定义注解Log
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
3.Log切面编程
@Component
@Aspect
@Slf4j
public class LogAspect {
ThreadLocal<Long> currentTime = new ThreadLocal<>();
/**
* 配置切入点
*/
@Pointcut("@annotation(com.leshu.framework.aspect.Log)")
public void logPointcut() {
}
/**
* 配置环绕通知,使用在方法logPointcut()上注册的切入点
*/
@Around("logPointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object result;
currentTime.set(System.currentTimeMillis());
result = joinPoint.proceed();
currentTime.remove();
log(joinPoint,result, null);
return result;
}
/**
* 配置异常通知
* @param joinPoint join point for advice
* @param e exception
*/
@AfterThrowing(pointcut = "logPointcut()", throwing = "e")
public void logAfterThrowing(JoinPoint joinPoint, Exception e) throws Throwable {
log((ProceedingJoinPoint) joinPoint,null, e);
}
public void log(ProceedingJoinPoint joinPoint,Object result, Exception e) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Log aopLog = method.getAnnotation(Log.class);
// 方法路径
String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
// 描述
String description = aopLog.value();
//参数值
Map<String, Object> params = null;
try {
params = getFieldsName(joinPoint);
} catch (Exception ex) {
log.error("日志切面异常", ex);
}
String res = result != null ? result.toString() : "error:" + StrUtil.sub(e.getMessage(), 0, 200);
log.info("methodName:【{}】,params:【{}】,description:【{}】,result:【{}】", methodName, params, description, res);
}
private Map<String, Object> getFieldsName(ProceedingJoinPoint joinPoint) throws Exception {
String classType = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
Class<?>[] classes = new Class[args.length];
for (int k = 0; k < args.length; k++) {
if (args[k] instanceof MultipartFile || args[k] instanceof ServletRequest || args[k] instanceof ServletResponse) {
return null;
}
if (!args[k].getClass().isPrimitive()) {
Class s = args[k].getClass();
classes[k] = s == null ? args[k].getClass() : s;
}
}
ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
Method method = Class.forName(classType).getMethod(methodName, classes);
String[] parameterNames = pnd.getParameterNames(method);
HashMap<String, Object> paramMap = new HashMap();
for (int i = 0; i < parameterNames.length; i++) {
paramMap.put(parameterNames[i], args[i]);
}
return paramMap;
}
}