zoukankan      html  css  js  c++  java
  • 注解

    注解

    注解概念

    什么是注解

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

    SpringBoot 全部都是采用注解化

    常用注解

    @Override     只能标注在子类覆盖父类的方法上面,有提示的作用

    @Deprecated    标注在过时的方法或类上面,有提示的作用

    @SuppressWarnings("unchecked")   标注在编译器认为有问题的类、方法等上面,用来取消编译器的警告提示,警告类型有serial、unchecked、unused、all

    元注解

    元注解用来在声明新注解时指定新注解的一些特性

    @Target 指定新注解标注的位置,比如类、字段、方法等,取值有ElementType.Method等

    @Retention 指定新注解的信息保留到什么时候,取值有RetentionPolicy.RUNTIME等

    @Inherited  指定新注解标注在父类上时可被子类继承

    常用注解

    @Target(ElementType.METHOD) // 指定新注解可以标注在方法上

    @Retention(RetentionPolicy.RUNTIME) // 指定新注解保留到程序运行时期

    @Inherited // 指定新注解标注在父类上时可被子类继承

    public @interface MayiktName {

        public String name();

    }

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

    注解的Target

    TYPE:类、接口(包括注解类型)和枚举的声明

    FIELD:字段声明(包括枚举常量)

    METHOD:方法声明

    PARAMETER:参数声明

    CONSTRUCTOR:构造函数声明

    LOCAL_VARIABLE:本地变量声明

    ANNOTATION_TYPE:注解类型声明

    PACKAGE:包声明

    TYPE_PARAMETER:类型参数声明,JavaSE8引进,可以应用于类的泛型声明之处

    TYPE_USE:JavaSE8引进,此类型包括类型声明和类型参数声明

    获取注解信息

             // 1.获取当前类上的注解
            Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");
    //        MayiktName declaredAnnotation = aClass.getDeclaredAnnotation(MayiktName.class);
    //        System.out.println(declaredAnnotation);
            // 2.获取当前方法上的注解
    //        Method userNameMethod = aClass.getDeclaredMethod("getUserName");
    //        MayiktName declaredAnnotation = userNameMethod.getDeclaredAnnotation(MayiktName.class);
    //        System.out.println(declaredAnnotation);
            // 3.获取字段上的注解
            Field pubUserName = aClass.getDeclaredField("pubUserName");
            final MayiktName declaredAnnotation = pubUserName.getDeclaredAnnotation(MayiktName.class);
            System.out.println(declaredAnnotation);

            // 4.获得构造方法注解

            Constructor<TestAnnotation> constructors = clazz.getConstructor(new Class[] {});// 先获得构造方法对象

            MyConstructorAnnotation myConstructorAnnotation = constructors.getAnnotation(MyConstructorAnnotation.class);// 拿到构造方法上面的注解实例

            System.out.println(myConstructorAnnotation.desc() + "+" + myConstructorAnnotation.uri());

    注解如何生效

    实际项目中 注解想生效通过反射+aop机制

    注解实现案例

    自定义限流注解

    对我们接口实现 限流 比如 每s 只能访问1次 或者每s 访问两次。

    Maven


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>
    <dependencies>
        <!--  springboot 整合web组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>

    </dependencies>

    使用谷歌的guava例子

        /**
         * 每秒生成2.0个令牌
         * //
         */
    //    private RateLimiter rateLimiter = RateLimiter.create(2.0);
        @GetMapping("/get")
    //    @MayiktCurrentLimit(name = "get", token = 1)
        public String get() {
    //        boolean result = rateLimiter.tryAcquire();
    //        if (!result) {
    //            return "当前访问人数过多,请稍后重试!";
    //        }
            return "my is get";
        }

    封装自定义注解限流框架

    整合自定义注解
    整合Aop实现接口限流

    package com.mayikt.service.aop;

    import com.google.common.util.concurrent.RateLimiter;
    import com.mayikt.service.annotation.MayiktCurrentLimit;
    import org.apache.commons.lang3.StringUtils;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;

    import java.util.concurrent.ConcurrentHashMap;

    /**
     * @author 余胜军
     * @ClassName ExtTransactionalAop
     * @qq 644064779
     * @addres www.mayikt.com
     * 微信:yushengjun644
     */
    @Aspect
    @Component
    public class CurrentLimitAop {
        /**
         * 每秒生成1.0个令牌 每s产生10 token
         */
    //    private RateLimiter rateLimiter = RateLimiter.create(1);
        private ConcurrentHashMap<String, RateLimiter> rateLimiters = new ConcurrentHashMap();

        @Around(value = "@annotation(com.mayikt.service.annotation.MayiktCurrentLimit)")
        public Object around(ProceedingJoinPoint joinPoint) {
            try {
                //获取拦截的方法名
                Signature sig = joinPoint.getSignature();
                //获取拦截的方法名
                MethodSignature methodSignature = (MethodSignature) sig;
                // 判断方法上是否有加上该注解,如果有加上注解则限流
                MayiktCurrentLimit mayiktCurrentLimit =
                        methodSignature.getMethod().getDeclaredAnnotation(MayiktCurrentLimit.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 "系统出现了错误!";
            }
        }
    }

    使用效果
    package com.mayikt.service;

    import com.google.common.util.concurrent.RateLimiter;
    import com.mayikt.service.annotation.MayiktCurrentLimit;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;

    /**
     * @author
    余胜军
     
    * @ClassName MemberService
     * @qq 644064779
     * @addres www.mayikt.com
     *
    微信:yushengjun644
     */
    @RestController
    public class MemberService {
        /**
         *
    每秒生成2.0个令牌
        
    * //
         */
    //    private RateLimiter rateLimiter = RateLimiter.create(2.0);
       
    @GetMapping("/get")
    //    @MayiktCurrentLimit(name = "get", token = 1)
       
    public String get() {
    //        boolean result = rateLimiter.tryAcquire();
    //        if (!result) {
    //            return "
    当前访问人数过多,请稍后重试!";
    //        }
           
    return "my is get";
        }

        @GetMapping("/add")
        @MayiktCurrentLimit(name = "add", token = 5)
        public String add() {
            return "my is add";
        }

        @GetMapping("/my")
        @MayiktCurrentLimit()
        public String my() {
            return "my is add";
        }
    }

    http://127.0.0.1:8080/get

    http://127.0.0.1:8080/my

  • 相关阅读:
    Mininet系列实验(六):Mininet动态改变转发规则实验
    Mininet系列实验(五):Mininet设置带宽之简单性能测试
    Mininet系列实验(三):Mininet命令延伸实验扩展
    Mininet系列实验(一):Mininet使用源码安装
    集合初始化器概览(Visual Basic)
    为什么开发人员不能估算时间?
    Lambda 表达式 Lambda Expressions (Visual Basic)
    宽松委托转换(Relaxed delegate conversion)
    [翻译]SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb
    Visual Basic 2010 新特性
  • 原文地址:https://www.cnblogs.com/angdh/p/15602226.html
Copyright © 2011-2022 走看看