springboot中通过aop的形式获取方法执行时间

来源:互联网 发布:新京报网络直播回看 编辑:程序博客网 时间:2024/06/04 18:07

前言

老大让本人写一个方法,获取controller中的每个方法的执行时间,大于一定时间的抓出来,后期做优化。网上找了一些方法,特此记录一下。

注意:这里需要各位同学对springboot有一定的了解。


话不多说,直接上代码:

aspect类:

package com.fengye.aspect;import com.fengye.common.enums.ResultEnum;import com.fengye.exception.MethodRunningTimeException;import lombok.extern.slf4j.Slf4j;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.springframework.stereotype.Component;/** * @Description Aop切面类 * @Author ZF * @Time 2017/8/14 11:12 */@Aspect@Slf4j@Componentpublic class HttpAspect {    /**     * 切入点     */    @Pointcut("execution( * com.fengye.controller.*.*.*(..))")    public void aopPointCut() {}    /**     * 统计方法耗时环绕通知     * @param joinPoint     */    @Around("aopPointCut()")    public Object timeAround(ProceedingJoinPoint joinPoint) {        long startTime;        long E_time;        Object obj;        try {            // 获取开始时间            startTime = System.currentTimeMillis();            // 获取返回结果集            obj = joinPoint.proceed(joinPoint.getArgs());            // 获取方法执行时间            E_time = System.currentTimeMillis() - startTime;        } catch (Throwable t) {            // 当方法中报异常时,会抛出这里的异常,            throw new MethodRunningTimeException(ResultEnum.METHOD_RUNNING_TIME_ERROR, t);        }        String classAndMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();        log.info("执行 " + classAndMethod + " 耗时为:" + E_time + "ms");        return obj;    }}

UserController类:

/**     * SwaggerUI 相关Demo     * 以api开头的注解基本都是SwaggerUI的注解,可以多了解     *     * @param id 测试id  117390L     * @return     */    @ApiOperation(value = "findUsersById()", notes = "根据id查询用户")    @PostMapping(value = "/findUsersById")    @ApiResponse(code = 1, message = "返回用户实体")    public Result findUsersById(@ApiParam(name = "id", value = "用户Id") Long id) {        Users users;        try {            System.out.println(keyValue);            /**             * log相关Demo             */            log.info("根据id为{}的查找用户", 117390);            log.warn("根据id为{}的查找用户", 117390);            log.error("根据id为{}的查找用户", 117390);            users = usersService.findUsersById(117400L);            /**             * 异常处理相关Demo             */            int i = 1 / 0;  // 此处异常        } catch (Exception e) {            // 此处抛出自定义异常: UserException            throw new UserException(ResultEnum.FIND_USER_BY_ID_ERROR, e);        }        return ResultUtils.success(users);    }

但是这里会有问题:
当方法正常执行时,没有问题,可以成功获取执行时间;
当方法内报异常时,这样会直接抛出aspect中的异常,即:
throw new MethodRunningTimeException(ResultEnum.METHOD_RUNNING_TIME_ERROR, t);
即代码中的从而覆盖掉方法内部中你的自定义异常 。即:
throw new UserException(ResultEnum.FIND_USER_BY_ID_ERROR, e);
如果当你项目无论是否异常约定的返回格式都是是统一的,而且要通过返回的准确信息来定位异常的话,这种方法就不太可取。

所以我这里还是使用最原始的方法来做:

package com.fengye.aspect;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;/** * @Description Aop切面类 * @Author ZF * @Time 2017/8/14 11:12 */@Aspect@Slf4j@Componentpublic class HttpAspect {    String methodName;      // 方法名    long startTime;         // 开始时间    /**     * 切入点     */    @Pointcut("execution( * com.fengye.controller.*.*.*(..))")    public void aopPointCut() {}    /**     * 统计方法耗时环绕通知     * @param joinPoint     */    // @Around("aopPointCut()")    // public Object timeAround(ProceedingJoinPoint joinPoint) {    //     long startTime;    //     long E_time;    //     Object obj;    //     try {    //         // 获取开始时间    //         startTime = System.currentTimeMillis();    //         // 获取返回结果集    //         obj = joinPoint.proceed(joinPoint.getArgs());    //         // 获取方法执行时间    //         E_time = System.currentTimeMillis() - startTime;    //     } catch (Throwable t) {    //         throw new MethodRunningTimeException(ResultEnum.METHOD_RUNNING_TIME_ERROR, t);    //     }    //     String classAndMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();    //     log.info("执行 " + classAndMethod + " 耗时为:" + E_time + "ms");    //     return obj;    // }    @Before("aopPointCut()")    public void doBefore(JoinPoint joinPoint) {        methodName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();        startTime = System.currentTimeMillis();    }    @After("aopPointCut()")    public void doAfter() {        long E_time = System.currentTimeMillis() - startTime;        log.info("执行 " + methodName + " 耗时为:" + E_time + "ms");    }    @AfterReturning(returning = "object", pointcut = "aopPointCut()")    public void doAfterReturning(Object object) {        log.info("response={}", object.toString());    }}

相关注解的知识,推荐一个链接 http://blog.csdn.net/rainbow702/article/details/52185827

原创粉丝点击