AOP-配合slf4j打印日志

基本思想

  1. 凡在目标实例上或在目标实例方法(非静态方法)上标注自定义注解@AutoLog,其方法执行时将触发AOP操作;
  2. @AutoLog只有一个参数,用来控制是否打印该方法的参数和返回结果的json字符串,默认不打印,通过@AutoLog(debug= true)开启
  3. 通过AOP拦截方法并打印日志

代码

package com.yan.mssm.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoLog {
    boolean debug() default false;
}
package com.yan.mssm.aop;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Optional;

@Component
@Aspect
public class AutoLogAspectJ {
    private static final String LOG_FORMAT = "[AOP-LOG]->Method {}: {}";
    private static final String BEGIN = "begin";
    private static final String END = "end";
    private static final String PARAMS = "params";
    private static final String RESULT = "result";
    private static Logger LOGGER;

    private static String toJsonString(Object object) {
        ObjectMapper objectMapper = new ObjectMapper();
        String result = null;
        try {
            result = objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            LOGGER.error(e.getMessage());
        }
        return result;
    }

    @Around(value = "@within(com.yan.mssm.aop.AutoLog) || @annotation(com.yan.mssm.aop.AutoLog)")
    public Object test(ProceedingJoinPoint point) throws Throwable {
        Class targetClass = point.getTarget().getClass();
        LOGGER = LoggerFactory.getLogger(targetClass);
        Signature signature = point.getSignature();
        String methodSignature = signature.toString();
        boolean debug = isDebug(targetClass, AutoLog.class, signature.toLongString());
        LOGGER.info(LOG_FORMAT, BEGIN, methodSignature);
        printParams(point, LOGGER, debug);
        Object result = point.proceed();
        printResult(LOGGER, debug, result);
        LOGGER.info(LOG_FORMAT, END, methodSignature);
        return result;
    }

    private void printResult(Logger logger, boolean debug, Object result) {
        if (debug) {
            Optional.ofNullable(result)
                    .ifPresent(o -> logger.info(LOG_FORMAT, RESULT, o));
        }
    }

    private void printParams(ProceedingJoinPoint point, Logger logger, boolean debug) {
        if (debug) {
            Object[] args = point.getArgs();
            if (args.length == 0) {
                return;
            }
            logger.info(LOG_FORMAT, PARAMS, toJsonString(args));
        }
    }

    private boolean isDebug(Class targetClass, Class autoLogClass, String longMethodSignature) {
        return targetClass.isAnnotationPresent(autoLogClass)
                && ((AutoLog) targetClass.getDeclaredAnnotation(autoLogClass)).debug()
                || Arrays.stream(targetClass.getDeclaredMethods())
                .filter(method -> method.toString().equals(longMethodSignature) && method.isAnnotationPresent(autoLogClass))
                .anyMatch(method -> method.getAnnotation(autoLogClass).debug());
    }

}

你可能感兴趣的:(Spring,aop)