Spring AOP日志记录请求信息

Java框架

浏览数:104

2019-8-23

AD:资源代下载服务

Spring有两大核心,IOC和AOP,关于AOP的理论都有了解,但是当问到你有用过AOP吗?如何用的呢?这就需要有实际的使用经验。

这里分享一个使用AOP记录请求日志的案例:

案例

  1. 定义切点,切点为使用@RequestMapping的注解
@Pointcut(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping)")
  1. 使用环绕增强,获取调用的方法名,以及传递的参数
 @Around("pointcut()")
    public Object log (ProceedingJoinPoint joinPoint) throws Throwable {
        Object proceed = joinPoint.proceed();
        Object[] args = joinPoint.getArgs();
        if(null==args || 0==args.length){
            return proceed;
        }
        //获取全方法名
        String methodName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        String pramer=null;
        try {
            Map<Integer, Object> map = new HashMap<Integer, Object>();
            for (int i = 0; i < args.length; i++) {
                Object obj = diffLog(args[i]);
                if (null != obj) {
                    if (obj instanceof String) {
                        pramer=(String)obj;
                        continue;
                    }
                    map.put(i, obj);
                }
            }
            pramer += JSONObject.toJSONString(map);
            logger.error("调用方法名为:【"+methodName+"】\n   入参为:{} \n 出参为:{}",pramer,JSONObject.toJSONString(proceed));
        }catch (Exception e){
            logger.error("记录日志发生异常,异常日志是{}",e);
        }
        return proceed;
    }

  1. 将切面配置为bean,并且启用Spring AOP即可。这里参考Spring AOP入门
<aop:aspectj-autoproxy proxy-target-class="true"/>

这样在请求我们的项目的时候,就能把请求信息记录下来了

完整代码:

@Component
@Aspect
public class LogAspect {

    private static final Logger logger= LoggerFactory.getLogger(getClass());

    @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void pointcut(){
    }
    @Around("pointcut()")
    public Object log (ProceedingJoinPoint joinPoint) throws Throwable {
        Object proceed = joinPoint.proceed();
        Object[] args = joinPoint.getArgs();
        if(null==args || 0==args.length){
            return proceed;
        }
        //获取全方法名
        String methodName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        String pramer=null;
        try {
            Map<Integer, Object> map = new HashMap<Integer, Object>();
            for (int i = 0; i < args.length; i++) {
                Object obj = diffLog(args[i]);
                if (null != obj) {
                    if (obj instanceof String) {
                        pramer=(String)obj;
                        continue;
                    }
                    map.put(i, obj);
                }
            }
            pramer += JSONObject.toJSONString(map);
            logger.error("调用方法名为:【"+methodName+"】\n   入参为:{} \n 出参为:{}",pramer,JSONObject.toJSONString(proceed));
        }catch (Exception e){
            logger.error("记录日志发生异常,异常日志是{}",e);
        }
        return proceed;
    }

    /**
     * 日志的分类
     * @param parm
     */
    private Object diffLog(Object parm) {
        ...
    }
}


最后

这里给出一个使用AOP记录日志的例子,除了记录日志,还可以用它监控,用法很多,需要摸索

参考

作者:Real_man