反射和注解

举报
左岸小镇_梦归 发表于 2021/07/10 05:08:54 2021/07/10
【摘要】 反射和注解 自定义注解

反射

反射技术的使用
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量(成员变量也称为类的属性)
Method类 代表类的方法
Constructor类 代表类的构造方法
1.getField、getMethod和getCostructor方法可以获得指定名字的域、方法和构造器。
2.getFields、getMethods和getCostructors方法可以获得类提供的public域、方法和构造器数组,其中包括超类的共有成员。
3.getDeclatedFields、getDeclatedMethods和getDeclaredConstructors方法可以获得类中声明的全部域、方法和构造器,其中包括私有和受保护的成员,但不包括超类的成员。

获取Class文件的三种方式

Class.forName("类全名");
类名.class;
实例.getClass();

根据Class创建实例

.newInstance();//调用的是无参构造器

私有属性,开启访问呢权限

.setAccessible(true);

对方法的调用

.invoke();

反射可以直接越过泛型检查

泛型用在编译期,编译过后泛型擦除(消失掉),所以是可以通过反射越过泛型检查的

注意点:反射越过泛型检查存放其他类型数据后,使用lambda表达式遍历报类型转换异常。lambda表达式会根据泛型进行类型强转。

注解

什么是注解
注解用来给类声明附加额外信息,可以标注在类、字段、方法等上面,编译器、JVM以及开发人员等都可以通过反射拿到注解信息,进而做一些相关处理

常用注解
@Override 只能标注在子类覆盖父类的方法上面,有提示的作用
@Deprecated 标注在过时的方法或类上面,有提示的作用
@SuppressWarnings(“unchecked”) 标注在编译器认为有问题的类、方法等上面,用来取消编译器的警告提示,警告类型有serial、unchecked、unused、all

元注解
元注解用来在声明新注解时指定新注解的一些特性
@Target 指定新注解标注的位置,比如类、字段、方法等,取值有ElementType.Method等
@Retention 指定新注解的信息保留到什么时候,取值有RetentionPolicy.RUNTIME等
@Inherited 指定新注解标注在父类上时可被子类继承

元注解就是我们开发人员自己定义注解会使用到。

自定义注解 运行 : 反射+aop实现的

注解的Target

TYPE:类、接口(包括注解类型)和枚举的声明
FIELD:字段声明(包括枚举常量)
METHOD:方法声明
PARAMETER:参数声明
CONSTRUCTOR:构造函数声明
LOCAL_VARIABLE:本地变量声明
ANNOTATION_TYPE:注解类型声明
PACKAGE:包声明
TYPE_PARAMETER:类型参数声明,JavaSE8引进,可以应用于类的泛型声明之处
TYPE_USE:JavaSE8引进,此类型包括类型声明和类型参数声明

反射获取注解信息

.getDeclaredAnnotation

自定义限流注解(demo)

了解谷歌的限流框架的基本使用

<dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>18.0</version>
</dependency>
/**
     * 每秒生成2.0个令牌
     * 
     */
    private RateLimiter rateLimiter = RateLimiter.create(2.0);
    @GetMapping("/get")
    public String get() {
       boolean result = rateLimiter.tryAcquire();
       if (!result) {
           return "当前访问人数过多,请稍后重试!";
       }
        return "my is get";
    }

封装限流注解的思路

1.需要自定义一个限流注解

每个请求方法限流规则不同

2.限流注解如何生效?

Spring Aop

环绕通知

1.先使用反射机制获取注解(查看是否有限流注解)

2.如果有该注解,调用限流api框架

@Aspect  //标注在类上,标识切面类
@Around(value = "@annotation(注解的全类名)")    public Object around(ProceedingJoinPoint joinPoint) {        try {            //获取拦截的方法名            Signature sig = joinPoint.getSignature();            //获取拦截的方法名            MethodSignature methodSignature = (MethodSignature) sig;            // 判断方法上是否有加上该注解,如果有加上注解则限流            注解类 mayiktCurrentLimit =                    methodSignature.getMethod().getDeclaredAnnotation(注解类.class);                        //可以不判断,走到这个环绕通知内,说明方法上肯定有该注解            //if (mayiktCurrentLimit == null) {                // 执行目标方法              //  return joinPoint.proceed();            //}                        // 获取注解上的name            String name = mayiktCurrentLimit.name();            // 获取注解上的token            double token = mayiktCurrentLimit.token();            RateLimiter rateLimiter = rateLimiters.get(name);            if (rateLimiter == null) {                rateLimiter = RateLimiter.create(token);                rateLimiters.put(name, rateLimiter);            }            // 开始限流            boolean result = rateLimiter.tryAcquire();            if (!result) {                return "当前访问人数过多,请稍后重试!";            }            return joinPoint.proceed();        } catch (Throwable throwable) {            return "系统出现了错误!";        }    }}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。