反射和自定义注解实战案例
Posted zhixuChen200
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射和自定义注解实战案例相关的知识,希望对你有一定的参考价值。
反射和自定义注解实战案例
前言
写该文章的目的主要复习一些注解和反射的内容,同时也让大家理解一下框架中这两样技术是如何运用的。
提示:以下是本篇文章正文内容,下面案例可供参考
一、反射API
- Class类:代表类的实体,在运行的Java应用程序中表示类和接口
- Field类:代表类的成员变量(成员变量也称为类的属性)
- Method类:代表类的方法
- Constructor类:代表类的构造方法
- getField、getMethod和getCostructor方法可以获得指定名字的域、方法和构造器。
- getFields、getMethods和getCostructors方法可以获得类提供的public域、方法和构造器数组,其中包括超类的共有成员。
- getDeclatedFields、getDeclatedMethods和getDeclaredConstructors方法可以获得类中声明的全部域、方法和构造器,其中包括私有和受保护的成员,但不包括超类的成员。
二、接口限流实战案例
该实战案例是通过使用谷歌的guavay与自定义注解相结合来实现接口限流。
1导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
</dependencies>
2.自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CzxLimit
/**
* name 限流的名称
*
* @return
*/
String name() default "";
/**
* 每s 能够允许访问的次数 10 底层
* 令牌桶
*
* @return
*/
double token() default 10;
说明:
-
token参数可以理解为该接口每秒最多可以访问几次。
3.定义控制层
@RestController
public class TestController
@GetMapping("/get")
@CzxLimit(name = "get", token = 1)
public String get()
return "get接口限制一秒钟登录一次";
@GetMapping("/add")
@CzxLimit(name = "add")
public String add()
return "add接口限制一秒钟登录10次(不填默认10次)";
@GetMapping("/push")
public String push()
return "push接口无限制";
说明:
- 控制层我们定义了三个方法,并在get()和add()方法上加入了自定义注解,说明get()该接口每秒最对访问一次,add()上的自定义注解未填token属性的值,说明默认每秒访问10次。
4.使用AOP环绕通知拦截方法
注解和接口都已经定义好,我们来看看是怎么实现限流的。
@Aspect
@Component
public class CzxLimitAop
private ConcurrentHashMap<String, RateLimiter> rateLimiters = new ConcurrentHashMap<>();
@Around(value = "@annotation(com.example.reflect.ano.CzxLimit)")
public Object around(ProceedingJoinPoint joinPoint)
try
//获取拦截的方法名
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
//获取到该注解
CzxLimit annotation = methodSignature.getMethod().getAnnotation(CzxLimit.class);
String name = annotation.name();
double token = annotation.token();
// 判断该名称是否有创建RateLimiter
RateLimiter rateLimiter = rateLimiters.get(name);
if (rateLimiter == null)
rateLimiter = RateLimiter.create(token);
rateLimiters.put(name, rateLimiter);
rateLimiter.tryAcquire();
//如果被限流的话
boolean result = rateLimiter.tryAcquire();
if (!result)
return "当前访问人数过多,请稍后重试!";
Object proceedResult = joinPoint.proceed();// 目标方法 public String get()
return proceedResult;
catch (Throwable throwable)
return "系统错误";
说明
- @annotation(com.example.reflect.ano.CzxLimit)注解的作用是,该环绕通知会拦截所有加上了该注解的接口。
- 通过joinPoint获取拦截的方法进而获取该注解,再根据注解参数进行限流控制。
以上是关于反射和自定义注解实战案例的主要内容,如果未能解决你的问题,请参考以下文章
JavaWeb1.3.3基础加强:注解案例(注解+反射重构"JavaWeb-1.2.3基础加强:案例(反射+配置文件))