Springboot AOP实现接口访问次数统计

一、理论基础

    1.1 AOP是什么

  • AOP(Aspect Oriented Programming)--面向切面编程

  • 可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术

    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
@Aspectpublic 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方法";
    }}

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用Spring AOP实现接口访问统计,可以按照以下步骤进行: 1. 定义一个注解@AccessCount,用于标记需要统计访问量的方法。 ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AccessCount { } ``` 2. 定义一个切面类AccessCountAspect,用于统计被@AccessCount标记的方法的访问量。这个类需要实现org.aspectj.lang.annotation.Aspect接口,并使用@Aspect注解标记。 ```java @Aspect @Component public class AccessCountAspect { private Map<String, Integer> accessCounts = new ConcurrentHashMap<>(); @Pointcut("@annotation(com.example.demo.annotation.AccessCount)") public void accessCountPointcut() {} @Around("accessCountPointcut()") public Object accessCountAround(ProceedingJoinPoint joinPoint) throws Throwable { String methodName = joinPoint.getSignature().toShortString(); int count = accessCounts.getOrDefault(methodName, 0); accessCounts.put(methodName, count + 1); return joinPoint.proceed(); } public Map<String, Integer> getAccessCounts() { return accessCounts; } } ``` 3. 在Spring配置文件中定义切面和切点。 ```xml <aop:aspectj-autoproxy/> <bean id="accessCountAspect" class="com.example.demo.aspect.AccessCountAspect"/> <aop:config> <aop:aspect ref="accessCountAspect"> <aop:pointcut id="accessCountPointcut" expression="execution(* com.example.demo.service..*(..))"/> <aop:around method="accessCountAround" pointcut-ref="accessCountPointcut"/> </aop:aspect> </aop:config> ``` 4. 在需要统计访问量的方法上添加@AccessCount注解。 ```java @Service public class UserServiceImpl implements UserService { @AccessCount @Override public User getUserById(Long id) { // ... } } ``` 5. 在需要获取访问量的地方,注入AccessCountAspect并调用getAccessCounts方法。 ```java @RestController @RequestMapping("/access-count") public class AccessCountController { @Autowired private AccessCountAspect accessCountAspect; @GetMapping("") public Map<String, Integer> getAccessCounts() { return accessCountAspect.getAccessCounts(); } } ``` 这样就可以使用Spring AOP实现接口访问统计了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值