当前位置:   article > 正文

Java自定义注解+AOP实现滑动时间窗口算法_java自定义注解实现aop

java自定义注解实现aop

前言

本文主要介绍如何定义实现注解,并配合AOP,来实现滑动时间窗口算法

一、介绍

1、注解

注解(Annotation)是Java中的一种特殊的元数据(metadata),JDK5.0新增的,它提供了一种在代码中添加标记和元数据的方式。注解可以用于类、方法、字段和其他程序元素上。

注解以@符号开头,紧跟着注解的名称和一对括号。注解可以包含元素,这些元素可以接受值。注解的元素可以是预定义的类型,如字符串、整数等,也可以是枚举类型或其他注解类型。

注解可以用于多种目的,例如:

  • 提供编译时的静态检查和验证。
  • 为代码生成工具提供信息,以生成额外的代码。
  • 在运行时通过反射获取注解信息,以实现特定的逻辑。

Java中有一些内置的注解,如@Override、@Deprecated和@SuppressWarnings。此外,你还可以自定义注解来满足特定的需求。

总之,注解是一种用于添加元数据和标记的机制,它可以在编译时和运行时提供有关代码的额外信息,我们使用注解,可以在不改变原有逻辑的情况下,补充一些逻辑。

2、AOP

AOP,面向切面编程,也是可以帮助我们在不修改现有代码的情况下,对程序的功能进行拓展,往往用于实现日志处理,事务控制等通用功能

常用的通知类型

  • @Before:在 joinpoint 方法之前执行
  • @AfterReturning:在joinpoint 方法正常执行后执行
  • @AfterThrowing:在 joinpoint 方法抛出异常时执行
  • @After:在joinpoint 方法之后执行,无论方法正常还是异常退出
  • @Around:在joinpoint 之前和之后执行

二、实现注解逻辑

通过@interface关键字来定义注解
@Retention指定注解的生命周期,RetentionPolicy.RUNTIME表示在运行时有效
@Target指定作用目标ElementType.METHOD就是要加在方法上才有效
定义了两个参数period,limitCount,来实现我们的逻辑

1、自定义注解

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SlideWindowLimit {

	/**
	 * 限制时间范围,单位ms
	 */
	long period() default 1000;

	/**
	 * 限制请求次数
	 */
	int limitCount() default 5;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

2、滑动时间窗口算法

主要Lua脚本来实现,另外还可以通过list和zset来实现,感兴趣的话,后面我再写一篇文章专门来分析

在这里插入图片描述

3、定义切面类

这里使用的是@Around环绕注解,目前只使用了前置增强,还可以使用后置增强,记录下调用等情况,感兴趣的话,大家可以实现下

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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class SlideWindowLimitAspect {

	@Autowired
	private SlideWindowUtils slideWindowUtils;

	// 配置切入点
	@Pointcut("@annotation(cn.forlan.annotation.SlideWindowLimit)")
	public void slideWindowLimitPointcut() {
	}

	@Around("slideWindowLimitPointcut()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		// 获取注解属性
		SlideWindowLimit slideWindowLimit = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(SlideWindowLimit.class);
		if (slideWindowUtils.slideWindowAlgorithmByLua(request.getRequestURI(), slideWindowLimit.limitCount(), slideWindowLimit.period())) {
			return "操作过于频繁,请稍后重试";
		}
		return pjp.proceed();
	}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

注:有多个增强类对同一方法进行增强,可以通过@Order(数字)可以设置优先级,数字越小,越先执行

三、使用注解

1、使用

上面定义的作用目标是方法,所以我们直接在方法上加自定义注解,@SlideWindowLimit(period = 10000, limitCount = 5),设置10秒内只能访问5次,如下图:
在这里插入图片描述

2、测试

我们通过Postman来快速调用5次,可以看到接口已经被限制,说明我们自定义的注解+AOP逻辑生效了
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/274753
推荐阅读
相关标签
  

闽ICP备14008679号