实战代码(四):Springboot AOP实现接口访问次数统计

2020-11-19  本文已影响0人  LY丶Smile

一、理论基础

1.1 AOP是什么

以上介绍来自百度百科-AOP

1.2 AOP能做什么

二、实战代码

2.1 依赖引入

<!-- AOP -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.9.4</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.12</version>
</dependency>

2.2 AOP示例

/**
 * API访问历史统计
 * @author yangjunqiang
 */
@Component
@Aspect
public class ApiVisitHistory {

    private Logger log = LoggerFactory.getLogger(ApiVisitHistory.class);

    ThreadLocal<Long> startTime = new ThreadLocal<>();

    /**
     * 定义切面
     * - 此处代表com.smile.demo.controller包下的所有接口都会被统计
     */
    @Pointcut("execution(* com.smile.demo.controller..*.*(..))")
    public void pointCut(){

    }

    /**
     * 在接口原有的方法执行前,将会首先执行此处的代码
     */
    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());
        //获取传入目标方法的参数
        Object[] args = joinPoint.getArgs();
        log.info("类名:{}", joinPoint.getSignature().getDeclaringType().getSimpleName());
        log.info("方法名:{}", joinPoint.getSignature().getName() );
        // 计数
        AtomicCounter.getInstance().increase();
    }

    /**
     * 只有正常返回才会执行此方法
     * 如果程序执行失败,则不执行此方法
     */
    @AfterReturning(returning = "returnVal", pointcut = "pointCut()")
    public void doAfterReturning(JoinPoint joinPoint, Object returnVal) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        log.info("所有接口的总点击:{}", AtomicCounter.getInstance().getValue());
    }

    /**
     * 当接口报错时执行此方法
     */
    @AfterThrowing(pointcut = "pointCut()")
    public void doAfterThrowing(JoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        log.info("接口访问失败,URI:[{}], 耗费时间:[{}] ms", request.getRequestURI(), System.currentTimeMillis() - startTime.get());
    }
}

2.3 定义接口,进行测试

@RestController
@RequestMapping("/demo/aop")
public class HelloController {

    @GetMapping("hello")
    public String hello() {
        return "hello World!";
    }

    @GetMapping("hello2")
    public String hello2() {
        int i = 1 / 0;
        return "测试报错的AOP方法";
    }
}

2.4 源码地址

https://github.com/lysmile/spring-boot-demo/tree/master/springboot-aop-demo

上一篇 下一篇

猜你喜欢

热点阅读